在宏

时间:2016-03-06 01:30:21

标签: c gcc c-preprocessor

使用:

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

将打印:

foo is 0, currently in (null)

使用时:

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

将打印:

currently in foo_bar, foo is 0

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

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

2 个答案:

答案 0 :(得分:6)

您可以使用错误的数据类型触发此问题。 E.g:

#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;
}

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

foo is 0, currently in main

for for x86(gcc -m32 test.c):

foo is 0, currently in (null)

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

反向顺序它有点工作,因为指针有更好的宽度处理,位仍然是错误的。

对于gcc / clang,-Wformat通常会在编译时捕获此类错误并发出警告。

答案 1 :(得分:0)

旧的非标准名称为__FUNCTION__。您应该立即更改所有代码以使用__func__。它们的定义/声明也略有不同。

虽然听起来你的编译器确实很麻烦。如果__func__有效,我会将其归结为没人再测试__FUNCTION__