how does printf know the address of a CString#39;s character data?(Printf如何知道一个字符串的字符数据的地址?)
本文介绍了Printf如何知道一个字符串的字符数据的地址?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
考虑此代码片段:
struct My {
operator const char*()const{ return "my"; }
} my;
CStringA s( "aha" );
printf("%s %s", s, my );
// another variadic function to get rid of comments about printf :)
void foo( int i, ... ) {
va_list vars;
va_start(vars, i);
for( const char* p = va_arg(vars,const char*)
; p != NULL
; p=va_arg(vars,const char*) )
{
std::cout << p << std::endl;
}
va_end(vars);
}
foo( 1, s, my );
这段代码产生了"直观"的输出"啊哈"。但我不知道这是怎么回事:
- 如果变量函数调用被转换为推送参数的指针,则printf将收到一个被解释为
const char*
的 - 如果变量函数调用正在对它调用
operator (const char*)
,为什么它不为我自己的类调用?
CStringA*
有人能解释一下吗?
编辑:添加了一个虚拟变量函数,该函数将其参数视为const char*
s。请注意,当它到达my
参数时,它甚至会崩溃...
推荐答案
C++98标准的相关文本§5.2.2/7:
在参数表达式上执行左值到右值(4.1)、数组到指针(4.2)和函数到指针(4.3)的标准转换。在这些转换之后,如果参数没有算术、枚举、指针、指向成员的指针或类类型,则程序的格式不正确。如果参数具有非POD类类型(第9条),则行为未定义。
因此正式行为未定义。
但是,给定的编译器可以提供任意数量的语言扩展,而Visual C++确实提供了。关于将参数传递给...
:,MSDN Library记录了Visual C++的行为
- 如果实际参数的类型为Float,则在函数调用之前将其提升为Double类型。
- 任何有符号或无符号的字符、短、枚举类型或位字段都使用整数提升转换为有符号或无符号整型。
- 类类型的任何参数都通过值作为数据结构传递;副本是通过二进制复制创建的,而不是通过调用类的复制构造函数(如果存在)来创建。
这篇文章没有提到有关Visual C++应用用户定义的转换的任何内容。
MSCString
被巧妙地布局,因此它的POD表示恰好是指向其以空结尾的字符串的指针。(sizeof(CStringA) == sizeof(char*)
)当它在任何printf样式函数中使用时,该函数Get只是传递了字符指针。
由于上面的最后一点和CString
的布局,所以这是可行的。
这篇关于Printf如何知道一个字符串的字符数据的地址?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
沃梦达教程
本文标题为:Printf如何知道一个字符串的字符数据的地址?
猜你喜欢
- 从父 CMakeLists.txt 覆盖 CMake 中的默认选项(...)值 2021-01-01
- 使用 __stdcall & 调用 DLLVS2013 中的 GetProcAddress() 2021-01-01
- 将函数的返回值分配给引用 C++? 2022-01-01
- 哪个更快:if (bool) 或 if(int)? 2022-01-01
- DoEvents 等效于 C++? 2021-01-01
- 如何提取 __VA_ARGS__? 2022-01-01
- OpenGL 对象的 RAII 包装器 2021-01-01
- 将 hdc 内容复制到位图 2022-09-04
- XML Schema 到 C++ 类 2022-01-01
- GDB 不显示函数名 2022-01-01