C99规范第6.7.3.8段规定
如果数组类型的规范包括任何类型限定符,则元素类型是合格的,而不是数组类型.如果函数类型的规范包括任何类型的限定符,则行为未定义.
在基本原理(逻辑页面87,物理页面94)中,给出了将平面指针转换为(可变长度)数组指针的示例.
void g(double *ap, int n)
{
double (*a)[n] = (double (*)[n]) ap;
/* ... */ a[1][2] /* ... */
}
Run Code Online (Sandbox Code Playgroud)
当然,如果数组ap未在函数内修改,则应将其标记为const,但是应该标记为
void g(const double *ap, int n)
{
const double (*a)[n] = (const double (*)[n]) ap;
/* ... */
}
Run Code Online (Sandbox Code Playgroud)
不保留const限定符,因为(每6.7.3.8)它适用于目标的元素而不是目标本身,它具有数组类型double[n].这意味着如果给出适当的标志(-Wcast-qual对于GCC),编译器会正确地抱怨.无法const用C 表示数组类型,但此强制转换非常有用且"正确".该-Wcast-qual标志对于识别数组参数的误用非常有用,但误报不鼓励使用它.请注意,索引a[i][j]更具可读性,并且对于许多编译器而言,生成更好的机器代码,ap[i*n+j]因为前者允许通过较少的分析从内循环中提升某些整数运算.
编译器是否应将此视为特殊情况,有效地将限定符从元素提升到数组类型以确定给定的强制转换是否删除限定符或是否应修改规范?没有为数组类型定义赋值,因此限定符总是应用于数组类型而不仅仅是元素,这与6.7.3.8形成鲜明对比?