void compute(int rows,int columns,double *data) { double (*data2D)[columns] = (double (*)[columns]) data; // do something with data2D } int main(void) { double data[25] = {0}; compute(5,5,data); }
有时,将参数视为多维数组是非常方便的,但它需要被声明为一个指向平面数组的指针.像上面的例子中的计算一样,将指针视为一个多维数组是安全的吗?我很确定内存布局保证正常工作,但我不知道标准是否允许以这种方式投射指针.
这是否会破坏任何严格的混叠规则?指针算术的规则如何?由于数据“实际上不是”一个double [5] [5],我们允许在data2D上执行指针算术和索引,还是违反了指针算术不会偏离适当数组的边界的要求? data2D甚至可以保证指向正确的地方,还是只保证我们可以将其转回并恢复数据?标准报价将不胜感激.
解决方法
C11 6.3.2.3说
A pointer to an object type may be converted to a pointer to a
different object type. If the resulting pointer is not correctly
aligned for the referenced type,the behavior is undefined.
所以实际的转换是很好的,只要这两个指针都具有相同的对齐方式.
然后,通过指针访问实际数据,C11 6.5给你一个关于“别名”的乱码文本墙,这是很难理解的.我会尝试引用我认为是这个具体情况的唯一相关部分:
“The effective type of an object for an access to its stored value is
the declared type of the object,if any.” /–/“An object shall have its stored value accessed only by an lvalue
expression that has one of the following types:
- a type compatible
with the effective type of the object,”/–/
- “an aggregate or union type that includes one of the aforementioned types among its
members”
(以上有时被称为“strict aliasing rule”,这不是正式的C语言术语,而是由编译器实现者组成的术语.)
在这种情况下,对象的有效类型是25倍的数组.您尝试将其转换为一个数组指针,数组为5双打.无论是与有效类型兼容的类型,还是作为包含类型的聚合,我不知道.但我确信它是两种有效的情况之一.