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

时间:2011-12-22 07:09:31

标签: c++

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

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

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

有什么特别的'\ 0'使#1合法且#2非法?

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

3 个答案:

答案 0 :(得分:8)

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

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

  

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

'\0'满足“求值为零的整数类型的整数常量表达式prvalue”的要求,因为char是整数类型而\0的值为零。

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

答案 1 :(得分:5)

'\0'只是写0的另一种方式。无论你如何编写0,我都认为这是合法的比较0指针是合法的,而将指针与任何其他非指针类型进行比较几乎没有任何有效意义。

答案 2 :(得分:1)

这是C ++的设计错误。该规则表示任何值为零的整型常量表达式都可以视为空指针常量。

idiotic 非常值得怀疑的决定允许使用空指针'\0'(如您所见),还可以使用(1==2)甚至!!!!!!!!!!!1之类的内容(示例)类似于“C ++编程语言”中的一个,不知道Stroustrup是否认为这确实是一个“酷”特征。)

这种歧义当与三元运算符语义和隐式转换规则混合时,IMO甚至会在语法定义中创建漏洞:我记得找到一个案例,其中三个编译器中的一个没有编译,另外两个编译器使用不同的语义编译。 ..并且在浪费了一天阅读标准并向专家询问cclc ++。我无法确定三个编译器中的哪一个是正确的。