C99规范的第6.7.3.8段规定:
如果数组类型的说明中包含任何类型限定符,则元素类型是被限定的,而不是数组类型。如果函数类型的说明中包含任何类型限定符,则行为是未定义的。
在解释(逻辑页面87,物理页面94)中,给出了将平面指针强制转换为(可变长度)数组指针的示例。
void g(double *ap, int n)
{
double (*a)[n] = (double (*)[n]) ap;
/* ... */ a[1][2] /* ... */
}
当函数内未修改数组
ap
时,应将其标记为const。但在代码中的转换操作不应该被保留。void g(const double *ap, int n)
{
const double (*a)[n] = (const double (*)[n]) ap;
/* ... */
}
由于(根据6.7.3.8)它应用于目标元素而不是目标本身,因此不保留“const”限定符,这意味着编译器会 rightly 抱怨(如果给出适当的标志(GCC 的“-Wcast-qual”)。 在C语言中没有办法表示“const”数组类型,但这种转换非常有用且“正确”。“-Wcast-qual”标志可用于识别数组参数的误用,但是假阳性会阻止其使用。请注意,索引“a [i] [j]”比“ap [i * n + j]”更易读,并且对于许多编译器而言,产生更好的机器代码,因为前者允许一些整数算术被提升出内部循环而不需要进行更多分析。
编译器是否应将其视为特殊情况,有效地从元素中提取限定符以确定给定转换是否删除限定符,还是应修改规范? 对于数组类型未定义赋值,因此将限定符始终应用于数组类型而不仅仅是元素是否会有影响,与6.7.3.8相反?
~(逻辑页N ≡ 物理页N)
时,它让我感到很烦。 - Lightness Races in Orbit