指针和空字符之间的比较是否合法?

3

比较指针和 '\0' 是否合法?

在 clang++ 的 trunk 版本上(25836be2c)

const char *a = "foo";

if(a == '\0')

出现一个错误:指针和整数之间的比较('const char *'和'int')

然而

if(a == 0)

正如预期的那样,不会产生任何错误。

空字符与空指针在指针比较中是等效的吗?这是编译器的一个错误吗?

另一个问题是,使用“-std=c++03”标志时不会出现此错误,但是使用“-std=c++11”标志时会出现此错误。然而,当我使用g++(v4.8.5)时,在这两个标准中都不会出现错误。


1
请注意,较新版本的GCC会报错。 - Sebastian Redl
在 C++11 之前它们是一样的;在 C++11 之后第一个是错误的。 - M.M
2
“null”字符与空指针在指针比较中等价吗?不是的。这向来是一种不良习惯,从未是个好主意。不存在“null”字符,但有一个NUL字符。存在nullptr,但那不是一个字符。绝对没有理由混淆这两个概念。 - Useless
另一种方式是:在标准C++中没有NUL(这是ASCII的事情)。但是有空字符,它被定义为具有值0的字符。 - M.M
@M.M - 说得好,我真的不喜欢“null”和“NULL”的命名方式,因为它似乎鼓励混淆,所以我养成了称字符为nul的习惯,以稍微减少歧义。 OP:确实有一个“null”字符,但将其与指针进行比较仍然没有用。 - Useless
2个回答

5
这是从C++03到C++14的变化。在C++03中,[conv.ptr]p1说:
一个空指针常量是一个求值为零的整数类型的整数常量表达式右值。
字符字面值是一个整数常量表达式。
在C++14中,[conv.ptr]p1说:
一个空指针常量是一个值为零的整数字面值或一个std::nullptr_t类型的prvalue。
字符字面值既不是整数字面值,也不是std::nullptr_t类型。
最初发布的C++11版本没有包含这个变化;然而,由于缺陷报告DR903,它被引入标准,在2013年1月(该DR的最后评论日期)之后的某个时间被纳入标准。
由于这个变化是DR的结果,编译器将其视为对现有标准的错误修复,而不是下一个标准的一部分,因此当使用-std=c++11时,Clang和GCC都会进行行为更改,而不仅仅是当使用-std=c++14时。然而,显然这个变化直到GCC 4.8之后才被实现。(具体来说,它似乎只在GCC 7及以上版本中实现。)

4

来自[conv.ptr]§1

空指针常量是一个值为零的整数字面值或类型为std::nullptr_­t的prvalue。[...]

'\0'不是整数字面值,而是字符字面值,因此不适用于转换。


在C标准中,字符常量被认为是int类型。但在C++中不是这样吗?您能否给我一个参考章节,说明'\0'是字符类型而不是整数类型? - MIA
@Pratik - 这不是一个标准参考,但是一个相关的问题 https://dev59.com/1nI95IYBdhLWcg3wvwoQ - Bo Persson
5
C 不等于 C++。它们是不同的编程语言,因此您不能期望它们有相同的行为。 - Algirdas Preidžius
@PratikBhatu 在C++中并非如此,但类型无关紧要。字符字面值在语法上与整数字面值不同,无论类型如何。 - n. m.
@PratikBhatu [lex.ccon]§2:"不以u8uUL开头的字符字面值是普通字符字面值。包含单个可在执行字符集中表示的c-char的普通字符字面值具有类型char,[...]" - Quentin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接