Ser*_*eyA 5 c++ language-lawyer
受到这个问题的启发:*(&arr + 1) - arr 如何给出数组 arr 元素的长度?
以下代码将计算数组的长度,尽管调用了未定义的行为:
int arr[] = {5, 8, 1, 3, 6};
size_t len = *(&arr + 1) - &arr[0]; // len is 5
Run Code Online (Sandbox Code Playgroud)
我相信,通过取消引用 (&arr + 1) 我们正在触发未定义的行为。但是,我们这样做的唯一原因是立即将结果衰减为int*,指向原始数组中最后一个元素之后的一个元素。由于我们没有取消引用这个指针,我们在定义的区域中很好。
因此,问题如下:是否有一种方法可以在int*不取消引用不可引用指针并保持定义的情况下衰减?
PS 强制免责声明:是的,我可以使用sizeof运算符和除法计算数组的大小。这不是问题的重点。
编辑: 我现在不太确定间接本身是未定义的。我发现http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#232从它看起来似乎有试图使间接本身合法化,但我没有能够在实际标准中找到任何与此相关的措辞。
所谓的“衰变”是标准语言中的“数组到指针的转换”,很明显你所要求的是不可能的:
\n\n\n\n\n\n\nNT\xe2\x80\x9d 的 \xe2\x80\x9carray 类型的左值或右值或 T\xe2\x80\x9d 未知边界的 \xe2\x80\x9carray 可以转换为 \xe2\x80 类型的纯右值\x9c 指向 T\xe2\x80\x9d 的指针
\n
不能有左值引用不存在的数组,并且右值(不是从左值转换而来)不能引用同一个数组。
\n\n现在澄清几点:
\n\n&arr + 1是一个通过对象末尾的指针,并且间接仅在指向实际对象的指针上定义。目前的问题是关于空指针的,它与传递对象末尾的指针无关。int arr[2][5];,因为不被视为数组的一部分,因此仍然是未定义的。*(&arr + 1)int*arr[0]&arr[1][0] - &arr[0][0]