nullptr不能直接赋给整数变量,因为它是std::nullptr_t类型,与int等整型完全不兼容,而NULL是宏(常为0),可能隐式转为整数导致类型混淆。

为什么 nullptr 不能直接赋给整数变量
因为 nullptr 是类型为 std::nullptr_t 的字面量,和 int 完全不兼容。用它初始化或赋值给 int、long 等整型变量会编译失败,而旧式 NULL(常定义为 0 或 0L)却可能悄悄转成整数,埋下类型混淆的隐患。
-
int x = nullptr;→ 编译错误,安全拦截 -
int y = NULL;→ 可能通过(尤其当NULL是0),但语义错误 - 函数重载时,
nullptr明确匹配指针形参;NULL可能意外匹配整数重载
在模板函数里传空指针,为什么必须用 nullptr
模板推导对字面量类型极其敏感。NULL 是宏,展开后是整数常量,模板实参推导不出指针类型;nullptr 是独立类型,能正确参与类型推导。
-
template<typename t> void f(T* p); f(NULL);</typename>→ 推导失败或报错 -
f(nullptr);→ 正确推导为f<:nullptr_t>(nullptr)</:nullptr_t>,再隐式转为T* - STL 容器如
std::vector::insert的迭代器参数,用NULL会导致编译失败,nullptr才合法
跨平台项目里 NULL 宏定义不一致带来的坑
不同标准库或编译器对 NULL 的定义可能不同:0、0L、0LL,甚至带 __null 扩展。这会影响函数重载决议、模板特化、SFINAE 行为,尤其在 C++11 之前混用 C 头文件时更明显。
- Linux GCC 常用
#define NULL __null(GCC 扩展),Clang 兼容但 MSVC 不认 -
printf("%p", NULL);在某些平台触发未定义行为,因NULL不是真正的指针类型 - 统一用
nullptr后,所有平台语义一致,且%p格式化也需配合static_cast<void>(nullptr)</void>
什么时候还能用 NULL?
基本没有正当理由。唯一可容忍的场景是维护非常老的 C++03 代码,且无法升级编译器或标准库;或者调用纯 C API 时,为保持与 C 头文件风格一致(但即便如此,nullptr 也能隐式转为 C 的空指针)。
立即学习“C++免费学习笔记(深入)”;
- C++11 起,
nullptr是标准空指针字面量,NULL已沦为历史包袱 - 现代项目中混用
NULL和nullptr会增加代码理解成本,且静态分析工具(如 clang-tidy)会警告 - 头文件里若看到
#define NULL 0,别改它——但你自己写新代码时,永远选nullptr
类型安全不是靠约定,是靠编译器拦住你。一旦习惯写 nullptr,就很难再容忍 NULL 那种模棱两可的“看起来像指针”的幻觉。










