【发布时间】:2020-04-29 18:54:34
【问题描述】:
编译器在编译代码时会出现分歧
int main()
{
constexpr int arr[3] = {};
static_assert((void*)(arr + 3) == (void*)(&arr + 1));
}
在 GCC 和 Clang 中,static_assert 不会触发,MSVC 认为 static_assert 失败 https://godbolt.org/z/dHgmEN
(void*)(arr + 3) == (void*)(&arr + 1) 应该评估为true,为什么?
【问题讨论】:
-
从过去指针的定义看来
(void*)(&arr + 1) == (void*)(&arr[1] + 1)必须持有,但&arr[2]的状态是模糊的 -
@M.M
(void*)(&arr + 1) == (void*)(&arr[1] + 1)必须持有的结束指针的定义似乎很清楚我似乎不清楚。 -
&arr + 1表示arr之后的内存中第一个字节的地址,&arr[1] + 1表示arr[1]之后的内存中第一个字节的地址,它们必须是同一个字节数组中没有尾随填充 -
@M.M 好的,如果数组的第一个元素与数组is fixed 具有相同的地址的问题,那么我会说对于 2 个元素的数组很清楚。但是,对于具有 3 个元素的数组,为什么超过
arr[2]末尾的指针不能与指向arr[1]的指针进行比较? -
哦,您是在试图提出数组元素可能不按其下标顺序的论点吗?如果是这样,那么这个问题是不诚实的。 FWIW 我不相信该标准支持这样的事情,即使它支持,如果有人愿意迎合这种迂腐的水平,这将是一个可以纠正的缺陷。例如。你刚刚链接到的东西。
标签: c++ arrays pointers language-lawyer