迫使数组衰减(由于缺少更好的标题) [英] Forcing a decay of the array (for the lack of better title)
问题描述
受此问题启发:以下代码将计算数组的长度,尽管会调用未定义的行为:
The following code will calculate the length of an array, albeit invoking undefined behavior:
int arr[] = {5, 8, 1, 3, 6};
size_t len = *(&arr + 1) - &arr[0]; // len is 5
我相信,通过取消引用(& ar + 1),我们可以触发未定义的行为.但是,我们这样做的唯一原因是立即将结果衰减为 int *
,指向原始数组中最后一个元素之后的一个元素.由于我们不取消引用该指针,因此我们位于定义的区域中.
I believe, that by dereferencing the (&arr + 1) we are triggering undefined behavior. However, the only reason we are doing this is to immediately decay the result into int*
, pointing to one element after the last one in original array. Since we do not dereference this pointer, we are well in defined zone.
问题就在下面:是否有一种方法可以衰减为 int *
而无需取消引用不足的指针并保持定义?
The question thus is following: is there a way to decay into int*
without dereferencing the undereferencable pointer and staying defined?
P.S.强制性免责声明:是的,我可以使用 sizeof
运算符和除法来计算数组的大小.这不是问题的重点.
P.S. Mandatory disclaimer: yes, I can calculate the size of an array with sizeof
operator and division. This is not the point of the question.
我现在不太确定间接本身是否未定义.我发现 http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 ,从中看来,似乎在试图使间接化本身合法化,但是我找不到任何能证明这种效果的措辞按照实际标准.
I am now less sure that the indirection itself is undefined. I have found http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232 and from it looks it seems like there was an attempt to legalize the indirection per se, but I was not able to find any wording to this effect in actual standard.
推荐答案
通常所说的衰变"是数组到指针的转换",很明显,您要问的是不可能的:
What is known as "decay" is "array-to-pointer conversion" in standardese, and it is clear that what you ask is impossible:
"N T的数组"或"T的未知边界的数组"类型的左值或右值可以转换为"T的指针"类型的prvalue.
An lvalue or rvalue of type "array of N T" or "array of unknown bound of T" can be converted to a prvalue of type "pointer to T"
不能有左值指的是非-存在的数组,并且右值(不是从左值转换而来)不能引用同一数组.
There can be no lvalue referring to a non-existent array, and a rvalue (not converted from the lvalue) can't refer to the same array.
现在要澄清几点:
-
& arr + 1
是指针通过对象的末尾,并且间接寻址为定义相同的数组,即使您将int arr [2] [5];
,*(& arr + 1)
衰减为int *
是 not 而不是数组arr [0]
的一部分,因此& arr [1] [0]-& arr [0] [0]
仍未定义.
&arr + 1
is a pointer pass the end of an object, and indirection is defined only on pointers to actual objects. The active issue is about null pointers, which isn't relevant to pointers pass the end of an object.- Pointer arithmetic is only defined on objects within the same array, even if you had
int arr[2][5];
,*(&arr + 1)
decayed asint*
is not considered part of the arrayarr[0]
, and so&arr[1][0] - &arr[0][0]
is still undefined.
这篇关于迫使数组衰减(由于缺少更好的标题)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!