为什么将指针与'\ 0'进行比较是可以的?(但不是'A')

Edd*_*onk 5 c++

我在代码中发现了一个错误,我将指针与'\ 0'进行了比较.

想知道为什么编译器没有警告我这个bug我试过以下.

#include <cassert>

struct Foo
{
    char bar[5];
};

int main()
{
    Foo f;
    Foo* p = &f;
    p->bar[0] = '\0';
    assert(p->bar == '\0');    // #1. I forgot [] Now, comparing pointer with NULL and fails.
    assert(p->bar == 'A');     // #2. error: ISO C++ forbids comparison between pointer and integer
    assert(p->bar[0] == '\0'); // #3. What I intended, PASSES
    return 0;
}
Run Code Online (Sandbox Code Playgroud)

'\ 0'有什么特别之处,它使#1合法,#2非法?

请在答案中添加引用或引用.

CB *_*ley 8

使其合法且定义良好的事实'\0'空指针常量,因此可以将其转换为任何指针类型以生成空指针值.

ISO/IEC 14882:2011 4.10 [conv.ptr]/1:

空指针常数是整数类型的整数表达式prvalue计算结果为零或类型的prvalue std::nullptr_t.空指针常量可以转换为指针类型; 结果是该类型的空指针值,并且可以与对象指针或函数指针类型的每个其他值区分开.这种转换称为空指针转换.

'\0'满足"求值为零的整数类型的整数常量表达式prvalue"的要求,因为它char是一个整数类型且\0值为零.

其他整数只能通过a显式转换为指针类型,reinterpret_cast只有当整数是将有效指针转换为足够大小的整数类型的结果时,结果才有意义.


Nat*_*man 5

'\0'只是一种不同的写作方式0.我猜这是合法的比较指针0是有道理的,无论你怎么写0,而几乎从来没有任何有效的意义来比较指针与任何其他非指针类型.

  • @BasileStarynkevitch,不,它是`std :: nullptr_t`类型的对象.但是,它被认为是一个空指针常量和"0",因此它*将*转换为适当类型的空指针值. (3认同)