Jer*_*fin 24

是的,您可以将地址超出数组末尾,但不能取消引用它.对于你的10个项目的数组,array+10将工作.有几次(由委员会,其他人)讨论是否&array[10]真的导致未定义的行为(如果确实如此,是否真的应该).它的底线是,至少根据当前标准(包括C和C++),它正式导致未定义的行为,但如果有一个单独的编译器实际上不起作用,任何参数中的任何人都无法找到或引用它.

编辑:一旦我的记忆是正确的一半 - 这是(部分)官方缺陷报告给委员会,至少一些委员会成员(例如,汤姆普拉姆)认为措辞已经改变,所以它不会导致不明确的行为.OTOH,DR从2000年开始,状态仍然是"起草",因此可以肯定它是否真的是固定的,或者可能是(我没有通过N3090/3092来弄清楚).

然而,在C99中,它显然不是未定义的行为.

  • 好答案。作为一个也许有趣的历史点,我实际上看到一个 C 编译器未能正确取消引用 &array[N]。它位于 HP-1000 主机上的 HP RTE 上。它在我的数组上方设置了一个内存“栅栏”,因此程序的地址空间中不存在引用地址。这甚至早于 1989 年的 C 标准,所以我认为可以肯定地说这个编译器已经不复存在了。 (2认同)

Mic*_*urr 10

正如其他答案所指出的那样,表达式array[10]相当于*(array + 10),这似乎会导致元素的未定义解引用刚好超过数组的末尾.但是,表达式&array[10]相当于&*(array + 10),并且C99标准明确了(6.5.3.2地址和间接运算符):

一元&运算符返回其操作数的地址.如果操作数具有类型''type'',则结果具有类型''指向类型''的指针.如果操作数是一元运算*符的结果,则不会对该运算符和&运算符进行求值,结果就好像两者都被省略,除了对运算符的约束仍然适用且结果不是左值.类似地,如果操作数是[]运算符的结果,&则不会对运算符和*由其暗示的一元[]进行求值,结果就像&删除了[]运算符并将运算符更改为+运算符一样.

因此,没有任何未定义的内容&array[10]- 没有发生取消引用操作.

  • C99不是C++. (7认同)