我可以看看那个地址吗?

可能重复:
通过C ++标准,通过下标:合法或不合法的方式获取一个最后一个数组元素的地址?

int array[10];

int* a = array + 10;   // well-defined
int* b = &array[10];   // not sure...

最后一行是否有效?


是的,您可以将地址放在数组的末尾,但不能对其进行解引用。 对于10个物品的array+10array+10将起作用。 几次(由委员会等人)争论是否&array[10]真的会导致不确定的行为(如果确实如此,是否真的应该这样做)。 它的底线是,至少根据现行标准(包括C和C ++)它会正式导致未定义的行为,但如果有一个编译器实际上不起作用,那么任何参数都没有人能够找到或引用它。

编辑:有一次,我的记忆是一半正确 - 这是(委员会的)一份官方缺陷报告(的一部分),至少有一些委员(如汤姆李梅)认为措辞已经改变,所以不会导致未定义的行为。 OTOH,DR的日期从2000年开始,状态仍然是“起草”,因此可以质疑它是否确实是固定的,或者很可能是(我没有通过N3090 / 3092了解)。

然而,在C99中,这显然不是未定义的行为。


正如其他答案指出的,表达式array[10]等价于*(array + 10) ,这看起来会导致刚刚超出数组末尾的元素的未定义解引用。 然而,表达式&array[10]等价于&*(array + 10) ,并且C99标准明确了(6.5.3.2地址和间接运算符):

一元&运算符返回其操作数的地址。 如果操作数的类型为''type'',则结果的类型为'',指向类型''。 如果操作数是一元*运算符的结果,那么该算子和&运算符都不会被计算,结果就好像两个都被省略一样,除了运算符的约束仍然适用并且结果不是左值。 同样,如果操作数是[]运算符的结果,则评估[]所隐含的&运算符和一元运算符* ,结果就好像&运算符已被删除, []运算符已更改为a +运算符。

所以,没有任何关于&array[10]未定义 - 没有取消引用操作发生。


array[10]相当于*(array + 10) (也相当于10[array] ),所以&array[10]就像从*(array+10)移除*一样。 任何体面的编译器都应该发出相同的代码(和相同的警告)。

链接地址: http://www.djcxy.com/p/72983.html

上一篇: May I take the address of the one

下一篇: Does std::list::remove method call destructor of each removed element?