2

This is the complete code. It is part of my home-made unit-test framework.

#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);
}

The compiler would claim:

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

Is it because the actual comparison is happened between pointer and int variable?

jiandingzhe
  • 1,881
  • 15
  • 35
  • 1
    If this doesn't work with any C++ compiler this compiler is wrong. – Dietmar Kühl Nov 06 '14 at 02:08
  • 4
    You may want to include the warning level and settings you're using, and a reproducible *complete* code sample, because this should work. [see it live](http://ideone.com/pVMZmd). – WhozCraig Nov 06 '14 at 02:08
  • 3
    ``if (foo_p == 0)` is perfectly valid; `0` is a *null pointer constant*. Please copy-and-paste the *exact* line of code that produces the error message. – Keith Thompson Nov 06 '14 at 02:09
  • 2
    Well the answer is that you *aren't* comparing the pointer to an `int` literal at all, you're comparing it to an `int` *variable.* – user207421 Nov 06 '14 at 02:30

3 Answers3

2

The literal 0 is a pointer or an integer literal depending on how it is used. When 0 is assigned or compared to a pointer it is considered a pointer literal. In other contexts, e.g., when deducing its type in a template, it is deduced to be an int and it is not compatible with a pointer. That is, you can use

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

... but you cannot use

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

The easiest way to avoid this problem entirely is not to use 0 for a null pointer literal and instead use nullptr.

Dietmar Kühl
  • 150,225
  • 13
  • 225
  • 380
1

Maybe you didn't show what you are currently doing that's why you should provide the warning level and settings you're using as pointed by WhozCraig. And maybe you want to compare the value pointed by foo_p and this can be pitfall as you are actually comparing addresses with:

if (foo_p == 0) {}

If you want to compare the value pointed by foo_p you must do:

if (*foo_p == 0) {}

EDIT:

The error is that you are trying to compare a pointer with an int variable:

ISO C++ forbids comparison between pointer and integer [-fpermissive]

And since your pointer is an struct you cannot compare with an int literal.

ranu
  • 622
  • 15
  • 25
1

0 is special in C++, besides as an int literal, it also means null pointer, so you can assign it to a pointer, and compare it with a pointer, such as:

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

BTW, it's better to use nullptr instead of 0 from c++11.

But int and pointer are different type, so you can't assign or compare them directly:

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

In your case, T1 is Foo*, T2 is int, they can't be compared directly.

songyuanyao
  • 169,198
  • 16
  • 310
  • 405