`*((*(&array + 1)) - 1)` 是否可以安全地用于获取自动数组的最后一个元素? [英] Is `*((*(&array + 1)) - 1)` safe to use to get the last element of an automatic array?
问题描述
假设我想获取一个大小未知的自动数组的最后一个元素.我知道我可以使用 sizeof
运算符来获取数组的大小并相应地获取最后一个元素.
Suppose I want to get the last element of an automatic array whose size is unknown. I know that I can make use of the sizeof
operator to get the size of the array and get the last element accordingly.
使用 *((*(&array + 1)) - 1)
安全吗?
Is using *((*(&array + 1)) - 1)
safe?
喜欢:
char array[SOME_SIZE] = { ... };
printf("Last element = %c", *((*(&array + 1)) - 1));
int array[SOME_SIZE] = { ... };
printf("Last element = %d", *((*(&array + 1)) - 1));
等
推荐答案
由于 Peter 在 他的回答中提到的原因,我认为这是未定义的行为.
I believe it's undefined behavior for the reasons Peter mentions in his answer.
关于*(&array + 1)
的争论很大.一方面,取消引用 &array + 1
似乎是合法的,因为它只是将类型从 T (*)[]
改回 T []
,但另一方面,它仍然是一个指向未初始化、未使用和未分配内存的指针.
There is a huge debate going on about *(&array + 1)
. On the one hand, dereferencing &array + 1
seems to be legal because it's only changing the type from T (*)[]
back to T []
, but on the other hand, it's still a pointer to uninitialized, unused and unallocated memory.
我的回答依赖于以下几点:
My answer relies on the following:
C99 6.5.6.7(加法运算符的语义)
就这些运算符而言,指向对象的指针是不是数组元素的行为与指向第一个元素的指针相同长度为 1 的数组的元素,以对象的类型为其元素类型.
For the purposes of these operators, a pointer to an object that is not an element of an array behaves the same as a pointer to the first element of an array of length one with the type of the object as its element type.
既然&array
不是指向数组元素的对象的指针,那么根据这个,就意味着代码等价于:
Since &array
is not a pointer to an object that is an element of an array, then according to this, it means that the code is equivalent to:
char array_equiv[1][SOME_SIZE] = { ... };
/* ... */
printf("Last element = %c", *((*(&array_equiv[0] + 1)) - 1));
也就是说,&array
是一个指向 10 个字符的数组的指针,因此它的行为与指向长度为 1 的数组的第一个元素的指针相同,其中每个元素都是一个数组10 个字符.
That is, &array
is a pointer to an array of 10 chars, so it behaves the same as a pointer to the first element of an array of length 1 where each element is an array of 10 chars.
现在,连同后面的条款(已经在其他答案中提到;这个确切的摘录是从 ameyCU 的答案中公然窃取的
Now, that together with the clause that follows (already mentioned in other answers; this exact excerpt is blatantly stolen from ameyCU's answer):
C99 第 6.5.6.8 节 -
[...]
如果表达式 P 指向数组对象的最后一个元素,则表达式 (P)+1 指向 [...]
如果结果指向数组对象的最后一个元素,则不应将其用作被评估的一元 * 运算符的操作数.
清楚地表明它是 UB:它相当于取消引用一个指针,该指针指向 array_equiv
的最后一个元素.
Makes it pretty clear that it is UB: it's equivalent to dereferencing a pointer that points one past the last element of array_equiv
.
是的,在现实世界中,它可能有效,因为实际上原始代码并没有真正取消对内存位置的引用,它主要是从 T (*)[] 的类型转换
到 T []
,但我很确定,从严格的标准合规性的角度来看,这是未定义的行为.
Yes, in real world, it probably works, as in reality the original code doesn't really dereference a memory location, it's mostly a type conversion from T (*)[]
to T []
, but I'm pretty sure that from a strict standard-compliance point of view, it is undefined behavior.
这篇关于`*((*(&array + 1)) - 1)` 是否可以安全地用于获取自动数组的最后一个元素?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!