c++ - c++中值0的特殊状态是什么?
问题描述
这纯粹是一个哲学问题。我假设没有合理的背景可以证明结果是有用的(给定的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
, 如果文字的值不存在可能的特定于实现的异常符合上述任何一项。这些类型都不能转换为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 *
转换的“幕后”会发生什么?
编辑:具体来说,问题是标准对此有何规定?
解决方案
问题是,为什么根据标准允许这样做
因为需要有一种方法来表达空指针。C 语言的设计者选择 0 为空。C++ 的设计者选择了与 C 兼容,因此 0 是一个空指针常量。
后来在 C++11 中,nullptr
作为新关键字被引入。整数空指针常量不能被替换,因为这会破坏向后兼容性,因此这些表示空值的不同方式并存。如果您不需要支持 C++11 之前的系统,则没有理由使用 0 作为空指针。
特别是允许的
标准说(最新草案):
[conv.ptr] 空指针常量是一个整数文字 ([lex.icon]),其值为 0 或 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);
自 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 了解不够,无法告诉您这些情况是否是故意的。我建议检查他们的文档。
推荐阅读
- node.js - Windows 10 上的 npm run build 给出了此应用程序无法在您的 PC 上运行
- csv - 如果数据中不存在分隔符值,则删除双引号
- google-apps-script - 如何对整列使用 indexOf?
- sorting - 用于排序的配对比较输入
- vba - 如何在没有对话框的情况下以 2 种不同的格式自动保存
- android - Android前台服务更新通知时震动
- angular - 是否可以在 Azure APIM 编写自定义代码
- javascript - Facebook 检测到应用程序未使用安全连接来传输信息
- javascript - 如何将 Jquery 值绑定到 HTML 元素
- google-apps-script - 按连接每月自动存档