在宏中使用__FUNCTION__

0x4*_*141 2 c gcc c-preprocessor

使用:

#define DEBUG_FOO(foo) fprintf(stderr, "foo is %x, currently in %s\n", foo, __FUNCTION__);
Run Code Online (Sandbox Code Playgroud)

将打印:

foo is 0, currently in (null)
Run Code Online (Sandbox Code Playgroud)

使用时:

#define DEBUG_FOO(foo) fprintf(stderr, "currently in %s, foo is %x\n", __FUNCTION__, foo);
Run Code Online (Sandbox Code Playgroud)

将打印:

currently in foo_bar, foo is 0
Run Code Online (Sandbox Code Playgroud)

这里发生了什么?我希望要么两者兼有,要么两者都将__FUNCTION__作为null.

使用的编译器是linaro arm-linux-gnueabihf-gcc

kel*_*tar 6

您可以使用错误的数据类型触发此问题.例如:

#include <stdio.h>
#include <stdint.h>

int main(int argc, char **argv) {
    uint64_t foo = 0;
    fprintf(stdout, "foo is %x, currently in %s\n", foo, __FUNCTION__);
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

如果为amd64架构编译,它可以正常工作:

foo is 0, currently in main
Run Code Online (Sandbox Code Playgroud)

对于x86(gcc -m32 test.c):

foo is 0, currently in (null)
Run Code Online (Sandbox Code Playgroud)

这就是可变参数函数参数的扩展,并且初始程序有一个bug.在那种特殊情况下,格式参数应该是"%"PRId64并且%x期望int.

由于指针具有更好的宽度处理,所以它的工作方式有点有效,但它仍然是错误的.

在gcc/clang的情况下,-Wformat通常在编译时捕获这种错误并发出警告.