为何C++的NULL通常是整型字面量而非C中那样的指针类型?
关于C++中NULL实现规则的合理性
- C没有沿用C中将NULL定义为
void*的规则,核心原因是两种语言的隐式转换规则差异:C允许void*类型隐式转换为任意指针类型,但C中该操作是非法的。如果C++直接对齐C的定义,那么最常用的int* p = NULL这类空指针初始化代码都会直接编译失败,完全无法满足基本使用需求。 - 标准允许将NULL实现为值为0的整型常量,是为了兼容C11之前的历史代码:C11才引入
nullptr和std::nullptr_t,此前二十多年的C++代码都使用0作为空指针常量,大量老代码存在依赖NULL可作为整型使用的写法(尽管这类写法并不规范),如果直接将NULL的类型改为std::nullptr_t,会导致海量存量代码无法编译。 - 至于GCC、Clang在64位平台将NULL实现为
long类型,是平台适配的合理选择:64位系统下指针宽度为8字节,long类型的宽度和指针一致,相比32位下常用的int类型实现,能避免部分复杂表达式场景下出现整型截断的意外问题。
关于与C标准的不兼容性
C和C从设计之初就并非完全兼容的语言,二者仅对公共语法子集的行为做了尽量对齐的约定。此处的差异是优先级选择的结果:对齐C的定义会导致C最核心的空指针使用场景失效,而保留现有规则仅会影响依赖NULL具体类型的边缘场景,二者相比显然优先保证核心功能的可用性。
实际开发中该不兼容性的影响极小:只要在C代码中将NULL仅作为空指针常量使用,不参与模板推导、不做类型相关判断,基本不会触发问题。如果需要在类型敏感的场景使用空指针,直接使用C11引入的nullptr即可完全避免类型歧义。
内容的提问来源于stack exchange,提问作者einpoklum
相关产品推荐
相关产品推荐

