【发布时间】:2018-06-08 03:28:03
【问题描述】:
我写了一个例子来说明我的问题,这里是使用嵌套宏来调用来检查数字是正数还是奇数。我知道使用这个调用是多余的,但正如我之前所说,它只是表明如果以嵌套方式使用宏,则会出现一些问题:
#include <stdio.h>
#include <stdlib.h>
#define num_is_positive_odd(num) \
({ \
int __rc = 0; \
int __num = (num); \
\
printf("%s:%d: check linenum\n", __func__, __LINE__); \
if (num_is_positive(__num) && num_is_odd(__num)) \
__rc = 1; \
__rc; \
})
#define num_is_positive(num) \
({ \
int __rc = 0; \
int __num = (num); \
\
if (__num > 0) { \
printf("%s: number %d is positive\n", \
__func__, __num); \
__rc = 1; \
} \
__rc; \
})
#define num_is_odd(num) \
({ \
int __rc = 0; \
int __num = (num); \
\
if (__num / 2) { \
printf("%s: number %d is odd\n", \
__func__, __num); \
__rc = 1; \
} \
__rc; \
})
int main()
{
int num = 4;
if (num_is_positive_odd(num++))
printf("%s: number %d is positive odd\n", __func__, num);
exit(0);
}
使用命令编译时:gcc -Wunused-variable chk_comps.c
显示错误:
chk_comps.c: In function ‘main’:
chk_comps.c:7:9: warning: unused variable ‘__num’ [-Wunused-variable]
int __num = (num); \
^
chk_comps.c:47:9: note: in expansion of macro ‘num_is_positive_odd’
if (num_is_positive_odd(num++))
^
`
有人可以帮助解释为什么以及如何解决它吗?谢谢。
【问题讨论】:
-
这不会扩展到有效的 C 代码。
-
这是使用名为statement expressions 的 GCC 扩展——因此规则特定于 GCC(并且可能是 Clang 模拟 GCC)。我不禁觉得你最好使用静态内联函数,而不是使用
__num名称(错误)在整个地方使用和(重新)使用的宏堆积在宏上。 -
请注意,通常不应创建以下划线开头的函数、变量或宏名称。 C11 §7.1.3 Reserved identifiers (部分)说: — 所有以下划线开头的标识符以及大写字母或另一个下划线始终保留供任何使用。 — 所有以下划线开头的标识符在普通名称空间和标记名称空间中始终保留用作具有文件范围的标识符。 另请参阅What does double underscore (
__const) mean in C? -
感谢您提供详细信息。
-
你到底为什么使用宏而不是函数?您在那里至少有 10 个运算符优先级错误。出于对混淆的热爱,将其重写为函数。提示:如果您这样做只是为了获取调用者的
__func__,那么只需执行一些包装宏,例如#define num_is_odd(num) number_is_odd(num, __func__),其中有bool number_is_odd (int num, const char* caller);。