用C常量数组类型的缺陷标准? [英] Constant array types in C, flaw in standard?
问题描述
C99的规范规定的第6.7.3.8
如果一个数组类型的特定连接的阳离子包括任何种类的合格网络连接器,该元素类型是所谓的合格网络版,而不是数组类型。如果一个函数类型的特定连接的阳离子包括任何种类的合格网络连接器,其行为定义理解过程网络。 块引用>在理由(逻辑第87页,94页物理),铸造扁指针(可变长度)阵列指针的一个实例。
无效克(双AP *,INT N)
{
双(*一)[N] =(双(*)[n])的AP;
/ * ... * /一[1] [2] / * ... * /
}当然,如果该阵列
AP
函数中没有被修改,应当标明常量,但是该浇铸在无效克(const的双AP *,INT N)
{
常量双(*一)[N] =(const的双(*)[n])的AP;
/ * ... * /
}确实因为(每6.7.3.8)不是preserve的
常量
预选赛它适用于目标,而不是目标本身的元素,其中有数组类型双[N]
。这意味着,编译器会正确地抱怨,如果给予适当的标志(-Wcast-QUAL
的GCC)。有没有办法来表示一个常量用C
数组类型,但这种转换是非常有用的,正确的。在-Wcast-QUAL
标志是识别的数组参数误用,但误报鼓励使用。注意索引A [I] [J]
既更具可读性,并与许多编译器,产生更好的机器code比AP [我* N + J]
,因为前者允许一些整数运算被吊出内部循环与分析较少。如果编译器只是把这个作为一个特殊的情况下,有效地从元素到数组类型起重预选赛来确定给定投是否删除预选赛还是应该规范进行修订?分配是不是数组类型定义,所以它会伤害了预选赛总是适用于数组类型,而不是仅仅的元素,而相比之下,6.7.3.8?
解决方案这是已经在过去的10年comp.std.c.多次讨论一个已知的问题底线是,具体的情况下,你presented目前不在标准C法律;需要移除这些限定符或从使用指针阵列来表示阵列中的合格元件避免
如果你认为你有一个好主意克服的问题,您可以将其发布到
新闻:comp.std.c
进行讨论。如果其他人都认为这是一个好主意,你或其他人可以提交缺陷报告有行为改变(有几个委员,经常comp.std.c所以从谁也可能被审查DR的人会反馈有用之前提交它有)。我想可能有一些问题,你的建议有预选赛影响阵列本身,但我必须给它多一些想法。Paragraph 6.7.3.8 of the C99 spec states
If the specification of an array type includes any type qualifiers, the element type is so-qualified, not the array type. If the specification of a function type includes any type qualifiers, the behavior is undefined.In the rationale (logical page 87, physical page 94), an example of casting a flat pointer to a (variable length) array pointer is given.
void g(double *ap, int n) { double (*a)[n] = (double (*)[n]) ap; /* ... */ a[1][2] /* ... */ }
Certainly if the array
ap
is not modified within the function, it should be marked const, however the cast invoid g(const double *ap, int n) { const double (*a)[n] = (const double (*)[n]) ap; /* ... */ }
does not preserve the
const
qualifier since (per 6.7.3.8) it applies to the elements of the target instead of the target itself, which has array typedouble[n]
. This means that compilers will rightly complain if given the appropriate flags (-Wcast-qual
for GCC). There is no way to denote aconst
array type in C, but this cast is very useful and "correct". The-Wcast-qual
flag is useful for identifying misuse of array parameters, but the false positives discourage its use. Note that indexinga[i][j]
is both more readable and, with many compilers, produces better machine code thanap[i*n+j]
since the former allows some integer arithmetic to be hoisted out of inner loops with less analysis.Should compilers just treat this as a special case, effectively lifting qualifiers from the elements to the array type to determine whether a given cast removes qualifiers or should the spec be amended? Assignment is not defined for array types, so would it hurt for qualifiers to always apply to the array type rather than just the elements, in contrast to 6.7.3.8?
解决方案This is a known issue that has been discussed several times over the last 10 years at comp.std.c. The bottom line is that the specific case you presented is not currently legal in Standard C; you need to either remove the qualifier or refrain from using a pointer to an array to refer to the qualified elements in the array.
If you think you have a good idea to overcome the issue, you can post it to
news:comp.std.c
for discussion. If others agree that it is a good idea, you or someone else can file a defect report to have the behavior changed (there are several committee members that frequent comp.std.c so feedback from the people who would potentially be reviewing the DR would be useful to have prior to filing it). I think there may be some issues with your proposal to have qualifiers affect the array itself, but I'd have to give it some more thought.这篇关于用C常量数组类型的缺陷标准?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!