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

C++标准是否对取数组索引表达式地址提供保证?含nullptr场景

C++中&指针[0]是否会因nullptr产生未定义行为?

首先看这段代码:

uint8_t my_array[3] = { 1, 2, 3 };
uint8_t *my_array_a = my_array;
uint8_t *my_array_b = nullptr;

uint8_t *my_element1 = &my_array_a[0];
uint8_t *my_element2 = &my_array_b[0];

注意:上述代码中所有类型的operator&和operator*均未重载。

在C标准(ISO/IEC 9899:TC2)中,计算my_element2时不会对my_array_b + 0进行解引用,标准原文如下:

类似地,如果操作数是[]运算符的结果,则&运算符和[]隐含的一元*都不会被求值,结果等价于移除&运算符并将[]改为+运算符。

现在的问题是:C++标准是否提供类似的保证(至少针对上述场景)?或者以这种方式计算my_element2是否因涉及解引用nullptr而属于未定义行为(UB)?

需要说明的是,我判断这段代码片段不存在隐藏的UB:将nullptr转换为uint8_t*是合法的,且nullptr + 0明确被定义为返回nullptr。该示例实用性不强,仅用于探讨规则本身。此问题类似Stack Exchange上的相关问题,但特别关注C++中是否存在&[]转换为+的等价保证——本示例未进行越界索引,但仍可能因是否实际解引用而存在UB。


在C++标准中,确实存在与C标准类似的语义保证,&my_array_b[0]不会触发对nullptr的解引用,不属于未定义行为。

根据C标准的定义,E1[E2]等价于*(E1 + E2)(这是C继承自C的核心规则)。但当我们对这个表达式取地址&*(E1 + E2)时,标准明确规定这里的一元*运算符不会被实际求值——因为&和*在这种上下文下会直接抵消,最终结果等价于E1 + E2。

回到你的场景:&my_array_b[0]等价于&*(my_array_b + 0),而由于*不会被求值,所以不会发生对nullptr的解引用操作。同时my_array_b + 0本身是合法的:指针与整数0相加,结果就是原指针值(此处为nullptr),这在C++标准中是明确定义的行为。

因此,uint8_t *my_element2 = &my_array_b[0];这段代码完全符合C++标准,不存在未定义行为。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 23:02:12