Ben*_*y K 3 c++ literals null-pointer
这纯粹是一个哲学问题。我认为没有合理的上下文可以证明结果是有用的(给定nullptr)。
根据这个 - https://en.cppreference.com/w/cpp/language/integer_literal,整数文字的类型是int, long int, long long int, unsigned int, unsigned long intor unsigned long long int,如果文字的值没有,则可能有特定于实现的例外适合以上任何一种。这些类型都不能转换为void *,除非文字的值为 0。
不同的编译器对此有不同的处理方式。例如,考虑以下转换:
void g(void * p){}
void f(){
int i = 0;
void * p;
// p = i; // Fails. Also for other integral types.
p = 0; // Works. Also for 00, 0x0 and 0b0. Also when adding `u` and `l` suffixes.
g(0); // Also works.
// g(1); // Fails.
// Amazingly, even this seems to work with gcc, icc and msvc, but not with clang:
void * x = static_cast<int>(0);
// These works for icc and msvc, but fails with gcc and clang
p = static_cast<int>(0);
g(static_cast<int>(0));
}
Run Code Online (Sandbox Code Playgroud)
使编译器能够执行这些int->void *转换的“幕后”会发生什么?
编辑:具体来说,问题是标准对此有何看法?
问题是,为什么根据标准允许这样做
因为需要有一种方式来表达空指针。C 语言的设计者选择 0 为空。C++ 的设计者选择与 C 兼容,因此 0 是空指针常量。
后来在 C++11 中,nullptr作为新关键字引入。不能替换整型空指针常量,因为那样会破坏向后兼容性,因此这些不同的空指针表示方式共存。如果您不需要支持 C++11 之前的系统,则没有理由使用 0 作为空指针。
尤其是允许的内容
标准说(最新草案):
[conv.ptr] 空指针常量是具有零值的整数文字 ([lex.icon]) 或类型为 std?::?nullptr_t 的纯右值。空指针常量可以转换为指针类型;结果是该类型([basic.compound])的空指针值,并且与对象指针或函数指针类型的所有其他值区分开来。这种转换称为空指针转换。相同类型的两个空指针值比较相等。将空指针常量转换为指向 cv 限定类型的指针是一次转换,而不是指针转换后跟限定转换 ([conv.qual]) 的序列。整数类型的空指针常量可以转换为 std?::?nullptr_t 类型的纯右值。[ 注意:生成的纯右值不是空指针值。— 尾注 ]
使编译器能够执行这些 int->void * 转换的“幕后”会发生什么?
编译器解析源。语法说 0 是文字。编译器将 is 视为文字 0,因此可以按照标准将其转换为任何指针类型。
// Amazingly, even this seems to work with gcc, icc and msvc, but not with clang:
void * x = static_cast<int>(0);
Run Code Online (Sandbox Code Playgroud)
这是自 C++11 以来格式错误的。当一个格式错误的程序编译时,通常是因为
在这种情况下,它可能是一种语言扩展。
// These works for icc and msvc, but fails with gcc and clang
p = static_cast<int>(0);
g(static_cast<int>(0));
Run Code Online (Sandbox Code Playgroud)
自 C++11 以来,这些也是格式错误的。我对 icc 和 msvc 了解不够,无法告诉您这些情况是否是故意的。我建议检查他们的文档。
| 归档时间: |
|
| 查看次数: |
126 次 |
| 最近记录: |