Den*_*rov 1 c++ arrays pointers
我已经阅读了标准的所有相关条款,但对于这种特殊情况,我无法正确解释它们:
const int arr[4][2] = {};
const int *ptr1 = (const int*)arr; // Is it OK/NOK and why?
const int *ptr2 = arr[0]; // Is this the same?
const int *ptr3 = &arr[0][0]; // Same?
Run Code Online (Sandbox Code Playgroud)
标准对这个演员有什么看法?
更新。
这是另一个相关的问题:
int i0 = ptr1[0];
int i2 = ptr2[2];
int i7 = ptr3[7];
Run Code Online (Sandbox Code Playgroud)
标准对直接从这些指针获取值有何看法?
根据标准,T 数组到 T 指针的数组是否在 C/C++ 中强制转换为合法操作?
Run Code Online (Sandbox Code Playgroud)const int *ptr1 = (const int*)arr; // Is it OK/NOK and why?
是的,这是合法的。arr将首先衰减到指向第一个元素的指针,即const int(*)[4]对象指针。const int *ptr也是对象指针类型。在 C++ 中,所有对象指针类型都可以显式转换为不同类型的对象指针。
然而,虽然强制转换是合法的,但由于“严格别名”规则,通过指针间接访问并尝试访问指向的对象是不合法的。洗后应该没问题:
auto ptr = std::launder(reinterpret_cast<const int*>(arr));
Run Code Online (Sandbox Code Playgroud)
但最好只使用:
auto ptr = &arr[0][0]
Run Code Online (Sandbox Code Playgroud)
这达到了相同的目的。但是,它无助于访问第一个子数组之外的元素。
UPD
Run Code Online (Sandbox Code Playgroud)const int *ptr2 = arr[0]; // Is this the same? const int *ptr3 = &arr[0][0]; // Same?
这些都不是演员表,两者都是格式良好的并且实际上是等效的。
这是另一个相关的问题:
Run Code Online (Sandbox Code Playgroud)int i0 = ptr[0]; int i2 = ptr[2]; int i7 = ptr[7];
即使洗钱,这也是未定义的行为。您只能arr[0]通过重新解释的指针进行访问,因为它是从指向第一个子数组的衰减指针派生的。访问ptr[0]并ptr[1]会被罚款你ptr2和ptr3我洗过的例子。