在查看一些代码时here,我看到一个宏,其中参数需要是字符串文字。
我发现了这个宏(来自 Jenn 的 Gustedt Modern C),它声称满足以下约束:
如果我有:
#define SV(str) (sizeof(str) - 1)
int main(void)
{
static const char *const s = "hello";
char word[] = "hello";
double a = 0.0f;
double *d = &a;
printf("%zu\n", SV(NULL));
printf("%zu\n", SV(word));
printf("%zu\n", SV(d));
printf("%zu\n", SV(s));
return 0;
}
代码编译正确,没有发出错误或警告,输出为:
7
5
7
7
但是如果我在其扩展中使用空字符串文字,情况就会改变
"" str ""
:
#define SV(str) (sizeof("" str "") - 1)
int main(void)
{
static const char *const s = "hello";
char word[] = "hello";
double a = 0.0f;
double *d = &a;
printf("%zu\n", SV(NULL));
printf("%zu\n", SV(word));
printf("%zu\n", SV(d));
printf("%zu\n", SV(s));
return 0;
}
现在如果我编译这个,我会得到:
macro_str.c: In function ‘main’:
macro_str.c:4:33: error: called object is not a function or function pointer
4 | #define SV(str) (sizeof("" str "") - 1)
| ^~
macro_str.c:19:21: note: in expansion of macro ‘SV’
19 | printf("%zu\n", SV(NULL));
| ^~
macro_str.c:4:40: error: expected ‘)’ before string constant
4 | #define SV(str) (sizeof("" str "") - 1)
| ~ ^~
macro_str.c:19:21: note: in expansion of macro ‘SV’
19 | printf("%zu\n", SV(NULL));
| ^~
macro_str.c:20:24: error: expected ‘)’ before ‘word’
20 | printf("%zu\n", SV(word));
| ^~~~
macro_str.c:4:36: note: in definition of macro ‘SV’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^~~
macro_str.c:4:32: note: to match this ‘(’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^
macro_str.c:20:21: note: in expansion of macro ‘SV’
20 | printf("%zu\n", SV(word));
| ^~
macro_str.c:21:24: error: expected ‘)’ before ‘d’
21 | printf("%zu\n", SV(d));
| ^
macro_str.c:4:36: note: in definition of macro ‘SV’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^~~
macro_str.c:4:32: note: to match this ‘(’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^
macro_str.c:21:21: note: in expansion of macro ‘SV’
21 | printf("%zu\n", SV(d));
| ^~
macro_str.c:22:24: error: expected ‘)’ before ‘s’
22 | printf("%zu\n", SV(s));
| ^
macro_str.c:4:36: note: in definition of macro ‘SV’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^~~
macro_str.c:4:32: note: to match this ‘(’
4 | #define SV(str) (sizeof("" str "") - 1)
| ^
macro_str.c:22:21: note: in expansion of macro ‘SV’
22 | printf("%zu\n", SV(s));
| ^~
make: *** [<builtin>: macro_str] Error 1
我的问题是:是否存在任何可能失败的边缘情况或漏洞?如果是这样,我该如何修改它以避免它们?
是否存在任何可能失败的边缘情况或漏洞?
这些编译没有抱怨:
printf("%zu\n", SV());
printf("%zu\n", SV(/*comment*/));
printf("%zu\n", SV(-));
printf("%zu\n", SV("abc" - "def"));