这纯粹是一个哲学问题。我认为没有合理的上下文可以证明结果是有用的(给定 nullptr
)。
据此 - https://en.cppreference.com/w/cpp/language/integer_literal ,整型文字的类型为 int
, long int
, long long int
, unsigned int
, unsigned long int
或 unsigned long long int
,如果文字的值不符合上述任何一项,则可能存在特定于实现的异常(exception)。
这些类型都不能转换为 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));
}
使编译器能够执行这些操作的“幕后”发生了什么
int
-> void *
转换?编辑:
具体来说,问题是标准对此有何规定?
最佳答案
The question is, why is this permitted according to the standard
因为需要有一种方式来表达空指针。 C 语言的设计者选择 0 为空。 C++ 的设计者选择与 C 兼容,因此 0 是空指针常量。
稍后在 C++11 中,
nullptr
被作为新关键字引入。不能替换整型空指针常量,因为那样会破坏向后兼容性,因此这些不同的空指针表示方式共存。如果您不需要支持 C++11 之前的系统,则没有理由使用 0 作为空指针。and specifically what is permitted
标准说(最新草案):
[conv.ptr] A null pointer constant is an integer literal ([lex.icon]) with value zero or a prvalue of type std::nullptr_t. A null pointer constant can be converted to a pointer type; the result is the null pointer value of that type ([basic.compound]) and is distinguishable from every other value of object pointer or function pointer type. Such a conversion is called a null pointer conversion. Two null pointer values of the same type shall compare equal. The conversion of a null pointer constant to a pointer to cv-qualified type is a single conversion, and not the sequence of a pointer conversion followed by a qualification conversion ([conv.qual]). A null pointer constant of integral type can be converted to a prvalue of type std::nullptr_t. [ Note: The resulting prvalue is not a null pointer value. — end note ]
What happens "under the hood" that enables compilers to perform these int->void * conversions?
编译器解析源。语法说 0 是文字。编译器将 is 视为文字 0,因此可以按照标准将其转换为任何指针类型。
// Amazingly, even this seems to work with gcc, icc and msvc, but not with clang:
void * x = static_cast<int>(0);
这是自 C++11 以来格式错误的。当一个格式错误的程序编译时,通常是因为
在这种情况下,它可能是一种语言扩展。
// These works for icc and msvc, but fails with gcc and clang
p = static_cast<int>(0);
g(static_cast<int>(0));
从 C++11 开始,这些也是格式错误的。我对 icc 和 msvc 了解不够,无法告诉您这些情况是否是故意的。我建议检查他们的文档。
关于c++ - c++中值0的特殊状态是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62025176/