我想知道当比较的相反目标是宏时,是否有一种简单/明智的方法可以让 gcc 停止抛出此错误。 是的,我认识到,通过 this 宏的特定定义,比较总是正确的,但它显然不能扩展到一般情况:
#define ROMBOT 0x00000000
#define ROMTOP 0x00002000
...
if (addr >= ROMBOT && addr < ROMTOP) {
simulator.c:517:2: error: comparison of unsigned expression >= 0 is always true
一种解决方案的效果是:
#if ROMBOT == 0
if (addr < ROMTOP) {
#else
if (addr >= ROMBOT && addr < ROMTOP) {
#endif
但这看起来真的很笨拙/维护成本很高。
或相关:
#define CHECK_ROM_BOT(_addr) (... etc)
但这很快就会升级为许多丑陋/不必要的宏。
大家有什么想法吗?
一种可能的方法是使用两个变量,这两个变量也许可以更改,因此:
uintptr_t rombot = ROMBOT;
uintptr_t romtop = ROMTOP;
if (addr >= rombot && addr < romtop)
如果这些变量在当前源文件外部可见,则它们可能会在编译器无法通过编译此文件看到的情况下发生更改,因此无法合法地警告比较。
#include <stdint.h>
#define ROMBOT 0x00000000
#define ROMTOP 0x00002000
uintptr_t rombot = ROMBOT;
uintptr_t romtop = ROMTOP;
extern int check_addr(uintptr_t addr);
int check_addr(uintptr_t addr)
{
if (addr >= ROMBOT && addr < ROMTOP)
return 1;
if (addr >= rombot && addr < romtop)
return 2;
return 0;
}
$ make xx.o
/usr/bin/gcc -g -std=c99 -Wall -Wextra -c -o xx.o xx.c
xx.c: In function ‘check_addr’:
xx.c:13: warning: comparison of unsigned expression >= 0 is always true
$
警告(因为我没有使用
-Werror
进行编译)会针对您的原始代码出现,而不是针对建议的替换代码出现。 您需要考虑变量的类型,但是 uintptr_t
可能是合理的。
其他人想到的另一个选项是在与 0 的比较中将 ROMBOT 强制转换为 double。这可能会生成额外的机器指令,具体取决于编译器。 转换值可能不准确,但根据 C11,6.3.1.4 第 2 项,它将具有正确的符号,这就是您所关心的。