【发布时间】:2008-11-20 13:28:10
【问题描述】:
C99 规范第 6.7.3.8 段声明
如果数组类型的规范包括任何类型限定符,则元素类型是如此限定的,而不是数组类型。如果函数类型的规范包含任何类型限定符,则行为未定义。
在rationale(逻辑页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;
/* ... */
}
不保留 const 限定符,因为(根据 6.7.3.8)它适用于目标的元素,而不是目标本身,它具有数组类型 double[n]。这意味着如果给出适当的标志(-Wcast-qual 用于 GCC),编译器将正确地抱怨。没有办法在 C 中表示 const 数组类型,但这种转换非常有用且“正确”。 -Wcast-qual 标志可用于识别数组参数的滥用,但误报会阻止其使用。请注意,索引a[i][j] 的可读性更高,并且与许多编译器相比,生成的机器代码比ap[i*n+j] 更好,因为前者允许将一些整数算术从内部循环中提升出来,而无需进行分析。
编译器是否应该将此视为一种特殊情况,有效地将限定符从元素提升到数组类型,以确定给定的强制转换是否删除了限定符,或者是否应该修改规范?没有为数组类型定义赋值,因此与 6.7.3.8 相比,限定符总是应用于数组类型而不仅仅是元素会不会造成伤害?
【问题讨论】:
-
~(logical page N ≡ physical page N)时让我感到很头疼。