为什么允许将int literal设置为指针,但是不比较?

时间:2014-11-06 02:04:41

标签: c++

这是完整的代码。它是我自制的单元测试框架的一部分。

#include <iostream>

#define IS(arg1, arg2) is(arg1, arg2, #arg1 " == " #arg2)

template<typename T1, typename T2>
void is(T1 value, T2 expect, const char* desc)
{
    if (value == expect)
    {
        std::cout << "ok " << " - " << desc << std::endl;
    }
    else
    {
        std::cout << "NOT ok " << " - " << desc << std::endl
                  <<"  got " << value <<", expect "<< expect << "  " << std::endl;
    }
}

struct Foo
{};

int main(int argc, char** argv)
{
    Foo* foo = 0;
    IS(foo, 0);
}

编译器声称:

test.cpp:8:15: error: comparison between pointer and integer ('Foo *' and 'int')
    if (value == expect)
        ~~~~~ ^  ~~~~~~

是因为实际的比较是在指针和int变量之间发生的吗?

3 个答案:

答案 0 :(得分:2)

文字0是指针或整数文字,具体取决于它的使用方式。将0分配或与指针进行比较时,它被视为指针文字。在其他上下文中,例如,当在模板中推断其类型时,它被推断为int并且与指针兼容。也就是说,你可以使用

Foo* pf = 0;
if (pf == 0) {}

...但无法使用

auto null = 0;
Foo* pf = null;    // ERROR
if (pf == null) {} // ERROR

完全避免此问题的最简单方法是0用于空指针文字,而是使用nullptr

答案 1 :(得分:1)

也许您没有显示您当前正在做的事情,以及为什么您应该提供您正在使用的警告级别和设置,如WhozCraig所指出的那样。也许你想比较foo_p指向的值,这可能是陷阱,因为你实际上是在比较地址:

if (foo_p == 0) {}

如果要比较foo_p指向的值,您必须执行以下操作:

if (*foo_p == 0) {}

编辑:

错误在于您尝试将pointerint变量进行比较:

ISO C ++禁止指针和整数之间的比较[-fpermissive]

由于您的指针是struct,因此您无法与int字面值进行比较。

答案 2 :(得分:1)

0在C ++中很特殊,除了作为int文字之外,它还意味着空指针,因此您可以将其指定给指针,并将其与指针进行比较,例如:

Foo* pf = 0;
if (pf == 0) {}

顺便说一句,最好使用nullptr代替0中的c++11

但是int和指针是不同的类型,所以你不能直接分配或比较它们:

int i = 0;
Foo* pf = i;    // compile error
if (pf == i) {} // compile error

在您的情况下,T1Foo*T2int,无法直接对其进行比较。