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

发布于 2024-10-15 17:31:45 字数 233 浏览 3 评论 0原文

#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 是问题所在。它确实有效,那么为什么它是危险的呢?

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

i am taking a class and have been asked to explain why this is bad... So i guess stringizing #a is the problem. It does work, so why is it dangerous?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

一江春梦 2024-10-22 17:31:45

因为它绕过了类型安全。 时会发生什么

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

当有人讨厌你并进行 print_int("5412");输出

$ 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

because it bypasses type safety. What happens when someone hates you and goes print_int("5412");

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

outputs

$ 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
失眠症患者 2024-10-22 17:31:45

我认为这一点也不坏。 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' < 24 | 'P' < <16 | ...)。事实上,它运行得很好,gcc 可以从中生成整数常量...有时...现在这很邪恶!

I don't think it's bad at all. The stringtize operator is very useful for writing macros like assertions:

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

You an abuse any useful feature. I once had the bright idea to "simplify" Qt Atoms by writing:

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

So you could say ATOM(MPEG) and get ('M' << 24 | 'P' << 16 | ...). In fact, it worked well enough that gcc could produce integer constants from it... Sometimes... Now that was evil!

百合的盛世恋 2024-10-22 17:31:45

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

int a = 15;
print_int(a++);

Preprocessor statements are generally considered evil. Bad things will happen when I say:

int a = 15;
print_int(a++);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文