我在代码中发现了一个错误,我将指针与'\ 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非法?
请在答案中添加引用或引用。
答案 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 ++。我无法确定三个编译器中的哪一个是正确的。