c - 在 c 复合语句中使用宏时
问题描述
我写了一个例子来说明我的问题,这里是使用嵌套宏来调用来检查数字是正数还是奇数。我知道使用这个调用是多余的,但正如我之前所说,它只是表明如果以嵌套方式使用宏,则会出现一些问题:
#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++))
^
`
有人可以帮助解释为什么以及如何解决它吗?谢谢。
解决方案
这是使用称为语句表达式的 GCC 扩展——因此规则特定于 GCC(并且可能是 Clang 模拟 GCC)。
如果您运行gcc -E
,您可以看到main()
(void
由我添加)的原始输出是:
# 41 "gccm43.c"
int main(void)
{
int num = 4;
if (({ int __rc = 0; int __num = (num++); printf("%s:%d: check linenum\n", __func__, 45); if (({ int __rc = 0; int __num = (__num); if (__num > 0) { printf("%s: number %d is positive\n", __func__, __num); __rc = 1; } __rc; }) && ({ int __rc = 0; int __num = (__num); if (__num / 2) { printf("%s: number %d is odd\n", __func__, __num); __rc = 1; } __rc; })) __rc = 1; __rc; }))
printf("%s: number %d is positive odd\n", __func__, num);
return 0;
}
其中,当手动格式化(“炼狱”主题的变体)时,可能看起来像:
# 41 "gccm43.c"
int main(void)
{
int num = 4;
if (({ int __rc = 0;
int __num = (num++);
printf("%s:%d: check linenum\n", __func__, 45);
if (({ int __rc = 0;
int __num = (__num);
if (__num > 0)
{
printf("%s: number %d is positive\n", __func__, __num);
__rc = 1;
}
__rc;
}) &&
({ int __rc = 0;
int __num = (__num);
if (__num / 2)
{
printf("%s: number %d is odd\n", __func__, __num);
__rc = 1;
}
__rc;
}
))
__rc = 1;
__rc;
}
))
printf("%s: number %d is positive odd\n", __func__, num);
return 0;
}
线条int __num = (__num);
有问题;您正在使用自身初始化变量,这并不能很好地完成(初始化前后的值是不确定的)。你还用来(__num / 2)
判断是否__num
是奇数,这是一种奇数检测奇数的方法;你应该使用(__num % 2)
.
现在也很明显为什么编译器会警告__num
未使用(其中一个)(变量)。外部声明分配num++
给__num
,但从不使用初始化变量,因为内部出现的int __num = (__num);
引用自身而不是外部__num
,因此不使用。
你最好使用静态内联函数——像这样:
#include <stdio.h>
#include <stdlib.h>
static inline int num_is_positive(int num)
{
int rc = 0;
if (num > 0)
{
printf("%s: number %d is positive\n", __func__, num);
rc = 1;
}
return rc;
}
static inline int num_is_odd(int num)
{
int rc = 0;
if (num % 2) // BUG fixed
{
printf("%s: number %d is odd\n", __func__, num);
rc = 1;
}
return rc;
}
static inline int num_is_positive_odd(int num)
{
int rc = 0;
printf("%s:%d: check linenum\n", __func__, __LINE__);
if (num_is_positive(num) && num_is_odd(num))
rc = 1;
return rc;
}
int main(void)
{
int num = 4;
if (num_is_positive_odd(num++))
printf("%s: number %d is positive odd\n", __func__, num);
return 0;
}
推荐阅读
- node.js - 在 Swagger openapi v3.0.0 中,面临多个文件上传的问题
- php - PHP MYSQL 在阿拉伯语中插入数据散列
- optimization - 在 Pytorch 中执行优化时如何对变量应用边界?
- python - 通过 simple-salesforce Python 访问 Salesforce 联系人记录的 ActivityMetric 字段
- swift - 如果是“是”,如何隐藏标签和文本字段,但也用下面的标签填充空白?
- javascript - 了解 indexOf 和 lastIndexOf
- docker - 导出使用 docker-compose 创建的容器
- javascript - 在表单保存按钮上首先触发哪个事件
- javascript - 为 Shopify 开发设置 webpack/HMR
- visual-studio-2017 - MDX 计算年份之间的利润差异(以 % 为单位)