我定义了一个自定义断言宏。这适用于所有其他比较。但是,我收到编译器错误:
ISO C++ forbids comparison between pointer and integer
使用下面显示的宏(DWASSERT)来比较指针,如下面的代码所示。
#define DWASSERT(condition,printstatement) if(!condition){ printf(printstatement); assert(condition); }
#include <stdio.h>
int main()
{
int target = 0;
int* ptr1 = ⌖
int* ptr2 = ⌖
//Normal comparison works fine
if(ptr1 == ptr2)
printf("Equal");
//Comparison using Macro generates compiler
//error on the next line
DWASSERT(ptr1 == ptr2, "Pointers not equal!\n");
return 0;
}
虽然我可以简单地避免在这种情况下使用DWASSERT,但我很好奇为什么会产生这个编译器错误。
答案 0 :(得分:8)
问题是DWASSERT(ptr1 == ptr2, ...
扩展为
if(!ptr1 == ptr2){ printf(...
你看到发生了什么事吗? !ptr1 == ptr2
等同于(!ptr1) == (ptr2)
,并且由于!ptr1
是整数类型而ptr2
是指针类型,因此您会收到错误。
解决此问题需要做的是将宏定义更改为:
#define DWASSERT(condition,printstatement) if(!(condition)){ printf...
另外,请记住,以任意字符串作为格式使用printf
是一种坏主意。在某些时候,有人会给你一个字符串,里面有%
,事情会破裂。您应该使用puts(x)
或printf("%s", x)
。
答案 1 :(得分:3)
更改
if(!condition)
要
if(! (condition) )
你采用这种方式,!
应用于比较中的第一个指针,而不是比较结果,它的优先级高于==
。
您应始终将宏参数括在括号中以避免类似问题。有时编译器不会警告你,你会在夜间寻找错误时听到你的声音。
答案 2 :(得分:1)
将括号括在宏的if
中的条件:
#define DWASSERT(condition,printstatement) if(!(condition)){ printf(printstatement); assert(condition); }
编译器看到了:
if (!ptr1 == ptr2) { ... }
解释为:
if ((!ptr1) == ptr2) { ... }
这不是你想要的。但你真的应该使用一个适当的函数 - 这个条件可能会用你的宏评估两次。可能存在第二次测试可能产生与第一次测试不同的结果的情况,这将产生非常令人惊讶的结果。
int i = -1;
DWASSERT(++i, "will I assert?");
(如果你真的必须使用宏,你应该在其中创建一个匿名块,并将条件的评估保存在临时bool
中。这通常使用do { ... } while(0)
构造。)
答案 3 :(得分:0)
尝试
DWASSERT((ptr==ptr2), "Pointers not equal!\n");