我在Windows和MSVC中编程。我知道有两种方法可以编写DEBUG_PRINT语句:
printf(__FUNCTION__": Error code: %x\n", ErrorCode);
printf("%s: Error code: %x\n", __FUNCTION__, ErrorCode);
将预定义的宏连接到这样的字符串是否可以?我不知道预定义的宏如__FUNCTION__
或__LINE__
是否是合法的字符串文字。直观地说,在C中处理这样的字符串似乎是一种危险的方式。
这两者有什么区别?由于我使用/ FAcs编译器选项将代码片段输出到程序集,我真的看不出太大差异。
答案 0 :(得分:2)
首先,__FUNCTION__
不在C标准中,你应该使用__func__
代替(除了微软决定在他们的C编译器中跳过对它的支持)。
第二个__FUNCTION__
/ __func__
"宏"实际上并不是一个宏(或者至少不是正常的 - 微软的编译器似乎行为不同),它的行为更像是局部变量,因此它不是字符串连接的候选者。您应该使用字符串格式(因为这将确保您的代码变得更加可移植)。
__LINE__
宏(是一个宏),但它不能直接与字符串连接一起使用,因为它不会扩展为字符串 - 它会扩展为一个数字(由方式在其他情况下可能有用)。但是,您可以使用预处理器对其进行字符串化(XSTR
宏将首先扩展它的参数然后对结果进行字符串化,而STR
在对字符串进行字符串化之前不会展开它的参数):
#define STR(x) # x
#define XSTR(x) STR(x)
printf("I'm on line #" XSTR(__LINE__));
__FILE__
宏(也是一个宏)确实扩展为一个字符串文字,它可以直接与字符串连接一起使用。
您没有看到任何差异的原因是编译器知道printf
做了什么,并且可以将其用于优化。它会发现它不需要依赖printf
代码来在运行时扩展%s
,因为它可以在编译时完成它。
答案 1 :(得分:1)
前者将__FUNCTION__
中的函数名与编译时的格式字符串连接起来。第二个将在运行时将其格式化为输出。
这假设它是一个预定义的宏(它不是标准的)。 MSVC将__FUNCTION__
作为正确的字符串文字,而GCC则没有。
__LINE__
,并扩展为十进制整数,即不是字符串。
出于性能原因,我建议在可能的情况下始终使用第一种方式,即当两个字符串是编译时常量时。像往常一样,要付出代价:字符串池会更大,因为每次使用宏都会创建一个唯一的格式字符串。对于桌面级系统,这可能是微不足道的。
答案 2 :(得分:0)
不同之处在于,在第一种情况下,字符串文字在编译器转换阶段与格式字符串连接,而在第二种情况下,它在运行时被读入。所以第一种方法要快得多。
如果您知道宏是预定义的字符串文字,我就不会发现代码有任何问题。
话虽如此,我不知道__FUNCTION__
是什么。有一个标准的C宏__func__
,但它不是一个字符串文字,应该被视为一个const char数组。
__LINE__
是一个标准的C宏,它将源文件行作为整数。
答案 3 :(得分:0)
感谢您的回答。看起来第一种方式是一个合法的文字字符串连接,它只是在构建时,它更快,只是占用空间。
我想我会坚持第一种方式。再次感谢。