我假设这Var
是一个指针对象,并且它的当前值是一个空指针。您的陈述暗示了这一点:
Var
第一次填充此结构时未初始化。(如NULL
:)
我还假设它Var
没有在块范围内定义。如果它是在块范围内定义的,并且您没有对其进行初始化或为其分配值,那么它的值就是垃圾,不一定是空指针值,并且任何引用其值的尝试都有未定义的行为。
行为未定义。
如果Var == NULL
,则&Var[N]
具有未定义的行为。
arr[index]
根据定义等价于*(arr + index)
,所以&Var[N]
等价于&(*(Var + N))
。指针算术的行为是根据指针指向的数组对象的元素定义的(单个对象被视为单元素数组),并且空指针不指向任何东西。
题外话:
C 明确表示&*x
被评估为x
,并且&[x[i])
被评估为x+i
; C++ 没有这样说,所以 的操作数&
必须是有效的。C++ 有一个加法的特殊情况0
,即使对于空指针也有很好的定义(C 没有这种特殊情况)。但&Var[0]
在 C 和 C++ 中仍然无效,但原因不同。在 C 中,它等价于Var + 0
,但添加0
到空指针具有未定义的行为。在 C++ 中,它不等同于Var + 0
; 而是相当于&(*(Var + 0))
; Var + 0
是一个空指针,并且取消引用它具有未定义的行为。)
题外话结束。
是的,仅仅计算一个无效地址具有未定义的行为,即使它从未被取消引用。
这是 2011 ISO C++ 标准 5.7 [expr.add] 第 5 段中的相关文本;特别注意最后:
当具有整数类型的表达式被添加到指针或从指针中减去时,结果具有指针操作数的类型。如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向与原始元素偏移的元素,使得结果和原始数组元素的下标之差等于积分表达式。换句话说,如果表达式 P 指向数组对象的第 i 个元素,则表达式 (P)+N(等效于 N+(P))和 (P)-N(其中 N 的值为 n)指向分别指向数组对象的第 i + n 个和第 i - n 个元素,前提是它们存在。此外,如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向数组对象的最后一个元素,如果表达式 Q 指向数组对象的最后一个元素,则表达式 (Q)-1 指向数组对象的最后一个元素。如果指针操作数和结果都指向同一个数组对象的元素,或者超过数组对象的最后一个元素,则计算不应产生溢出;否则,行为未定义。