C ++:使用宏比较指针时的编译器错误

时间:2011-12-31 21:54:01

标签: c++ macros assert

我定义了一个自定义断言宏。这适用于所有其他比较。但是,我收到编译器错误:

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 = &target;
    int* ptr2 = &target;

    //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,但我很好奇为什么会产生这个编译器错误。

4 个答案:

答案 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");