在define中字符串化#a,为什么不好

时间:2011-02-01 21:57:32

标签: c printf c-preprocessor

#include <stdio.h>
#define print_int(a) printf("%s : %d\n",#a,(a))
int main(void) {
    int y = 10;
    print_int(y);
    return 0;
}

我正在上课,并被要求解释为什么这很糟糕...所以我猜字符串#a是问题所在。它确实有效,为什么它很危险?

3 个答案:

答案 0 :(得分:3)

因为它绕过了类型安全。当有人讨厌你并且去print_int("5412");

时会发生什么
#include <stdio.h>
#define print_int(a) printf("%s : %d\n",#a,(a))
int main(void) {
    print_int("1123123");
    return 0;
}

输出

$ gcc test.c 
test.c: In function ‘main’:
test.c:4: warning: format ‘%d’ expects type ‘int’, but argument 3 has type ‘char *’
$ ./a.out 
"1123123" : 3870

答案 1 :(得分:2)

我认为这根本不好。 stringtize运算符对于编写断言等宏非常有用:

#define assert(x) do { if (!(x)) { printf("assert failed: %s\n", #x); } } while (0)

您滥用任何有用的功能。我曾经有一个明智的想法,通过写作来“简化”Qt Atoms:

#define ATOM(x)  (((#x)[0] << 24) | ((#x)[1] << 16) | ...

所以你可以说ATOM(MPEG)并获得('M' << 24 | 'P' << 16 | ...)。实际上,它运行良好,gcc可以从中产生整数常量......有时候......现在那是邪恶的!

答案 2 :(得分:1)

预处理程序语句通常被认为是邪恶的。当我说:

时会发生不好的事情
int a = 15;
print_int(a++);