我想知道当比较的对方目标是宏时,是否有一种简单/理智的方式让gcc停止抛出此错误。是的,我认识到使用这个宏的特定定义,比较总是正确的,但它显然不会扩展到一般情况:
#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)
但很快就会升级为许多丑陋/不必要的宏。
有人有什么想法吗?
答案 0 :(得分:0)
一种可能的方法是使用两个可能会改变的变量,因此:
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
可能是合理的。
答案 1 :(得分:0)
其他人想到的另一种选择是在比较0时将ROMBOT强制转换为两倍。这可能会生成额外的机器指令,具体取决于编译器。强制转换值可能不准确,但是根据C11 6.3.1.4第2项,它将具有正确的符号,这就是您所关心的。