You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向空指针(nullptr)加0是否属于未定义行为(UB)?

空指针加0是否属于未定义行为?

我确认这个问题之前有人提过,但没找到相关解答。如果有一个初始化为nullptr的char*空指针,对它执行加0操作是否属于未定义行为(UB)?我没找到任何说明“向空指针执行所有加法操作都是UB”的表述,但推测除加0外的其他加法操作肯定是UB。

示例代码:

char* buf = nullptr;
buf += 0; // UB?

实际场景中,我有一些可能为(nullptr, 0)的指针-长度对,部分函数会在不解引用指针的前提下修改这个对,可能出现向空指针加0的情况,请问需要添加if (ptr != nullptr)的判断吗?还是说这属于冗余代码?

另外,我知道在constexpr求值中执行UB会导致编译错误,所以尝试了以下代码:

static_assert([](char* buf){ buf += 0; return buf == nullptr; }(nullptr) == true);
static_assert([](char* buf){ buf += 1; return buf == nullptr; }(nullptr) == false);

后者因为向空指针加1编译失败,报错信息如下:

  • GCC: “arithmetic involving a null pointer”
  • Clang: “cannot perform pointer arithmetic on null pointer”
  • MSVC build: “failure was caused by unevaluable pointer value”
  • MSVC IntelliSense: “invalid arithmetic on non-array pointer”

但前者在GCC 12.1.0、Clang 15.0.0和MSVC 19.34.31942编译器中都能正常通过。这是不是说明向空指针加0不属于UB,还是仅仅说明该操作在这些编译器中定义良好?


结论:向空指针加0不属于未定义行为

根据C++标准中[expr.add]条款的规定,指针加法存在明确的合法例外:

当整数类型表达式J与指针类型表达式P相加时,结果类型与P一致:

  1. 若P求值为空指针值且J求值为0,结果为空指针值;
  2. 否则,若P指向数组对象x的某个元素,且J的值j满足0 ≤ j < n(n为数组元素总数),则P + J指向x[j];否则行为未定义;
  3. 其他情况,行为未定义。

显然,空指针加0属于上述第1种情况,是标准明确保障的合法操作,结果仍为空指针,不存在未定义行为。

对constexpr测试结果的解释

你观察到的编译器行为完全符合标准要求:

  • 空指针加1属于第3种情况,触发未定义行为,而constexpr求值阶段会严格检查UB,因此编译器直接报错;
  • 空指针加0符合合法规则,所以编译器允许constexpr求值通过,这不是编译器的“特殊处理”,而是严格遵循标准的结果。

实际场景的代码建议

不需要添加if (ptr != nullptr)的判断,空指针加0是标准保证的合法操作,额外的分支判断属于冗余代码。你可以直接保留指针-长度对的现有处理逻辑,无需针对空指针加0的情况做特殊分支。


内容的提问来源于stack exchange,提问作者Bolpat

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 10:37:12