如何优雅地避免对这种特定类型的 for 循环发出 "condition is always true" 警告?
How to elegantly avoid "condition is always true" warning for this particular kind of for-loop?
假设我们有以下 for 循环:
#define UPPER 0U
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
这会产生一个W549: condition is always true
警告,显然是因为我们在宏扩展后得到了for(i = 0; i < 0; i++)
。在实际代码中,UPPER
是一个预编译时间参数(即由一些构建脚本根据目标平台等设置),可以取 0 到 255 之间的任何值,因此循环不是只是死代码。
当UPPER == 0
时如何优雅地避免这个警告?
显然,可以将 for 循环包装在 if 语句中:
#define UPPER 0U
if(UPPER != 0U) {
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
}
但这不是我所说的优雅。
如果不想用代码包装,使用条件编译包装代码:
#if UPPER > 0
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
#endif
优雅源于:
- 当
UPPER
为0时无死码。
- 完全可移植到 1970-01-01 以来的任何 C 编译器
- 易于阅读和理解
不是很好的编码风格,但解决了任务。即使关闭优化,g++ 也会消除死代码。
#define UPPER 0U
int i;
for(i = 0; &((char*)0)[i] < &((char*)0)[UPPER]; i++) {
/* foo */
}
它消除了 signed
与 unsigned
比较的警告,并阻止编译器优化代码。
#define UPPER 0U
int i;
volatile int u = UPPER;
for(i=0; i < u; i++){
/* foo */
}
使用gcc -Wall -Wextra myfile.c
测试编译
假设我们有以下 for 循环:
#define UPPER 0U
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
这会产生一个W549: condition is always true
警告,显然是因为我们在宏扩展后得到了for(i = 0; i < 0; i++)
。在实际代码中,UPPER
是一个预编译时间参数(即由一些构建脚本根据目标平台等设置),可以取 0 到 255 之间的任何值,因此循环不是只是死代码。
当UPPER == 0
时如何优雅地避免这个警告?
显然,可以将 for 循环包装在 if 语句中:
#define UPPER 0U
if(UPPER != 0U) {
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
}
但这不是我所说的优雅。
如果不想用代码包装,使用条件编译包装代码:
#if UPPER > 0
int i;
for(i = 0; i < UPPER; i++) {
/* foo */
}
#endif
优雅源于:
- 当
UPPER
为0时无死码。 - 完全可移植到 1970-01-01 以来的任何 C 编译器
- 易于阅读和理解
不是很好的编码风格,但解决了任务。即使关闭优化,g++ 也会消除死代码。
#define UPPER 0U
int i;
for(i = 0; &((char*)0)[i] < &((char*)0)[UPPER]; i++) {
/* foo */
}
它消除了 signed
与 unsigned
比较的警告,并阻止编译器优化代码。
#define UPPER 0U
int i;
volatile int u = UPPER;
for(i=0; i < u; i++){
/* foo */
}
使用gcc -Wall -Wextra myfile.c