指针声明符的 C 标准描述是否有错误?

Is there a mistake in the C standard description of pointer declarators?

C 2018 6.7.6.1 1 说:

If, in the declaration “T D1”, D1 has the form

    * type-qualifier-listopt D

and the type specified for ident in the declaration “T D” is “derived-declarator-type-list T”, then the type specified for ident is “derived-declarator-type-list type-qualifier-list pointer to T”. For each type qualifier in the list, ident is a so-qualified pointer.

这道题是关于最后一句话的,但我们先完成第一句。

考虑声明 int * const * foo。这里TintD1* const * footype-qualifier-listconstD* foo.

那么T Dint * foo,并且为ident指定“指向int的指针”foo,所以 derived-declarator-type-list 是“指针”。 (标准中没有对 derived-declarator-type-list 的公开解释,但是 6.7.8 3,讨论 typedef,说它“由声明符指定D.”)

将这些代入第一句的最后一个子句告诉我们 T D1 指定 foo 的类型是“指向 const 的指针int”。目前还好。

但是最后一句话告诉我们,对于列表中的每个类型限定符(即 const),ident 是一个如此限定的指针。所以它说 foo 是一个 const 指针。

但事实并非如此;我们通常将 int * const * foo 解释为将 foo 声明为非 const 指向 const 指向 int.

的指针

这是标准中的错误还是对最后一句话有另一种解释?

TintD* foo,“T D”不给出ident类型T,但是指向T的指针。

第二部分if

If ... and the type specified for ident in the declaration “T D” is “derived-declarator-type-list T”

似乎可以确保 嵌套 是正确的。

如果有两颗星,则在到达直接声明符之前必须使用 D2 - D1 - D。

第二个例子:

typedef int *int_ptr;
const int_ptr foo;

显示它有多么棘手; const 远离 ident,但指针仍然是常量,而不是数据。

规范称之为澄清 - 现在 是一个错误。


有趣的是,在下一节“6.7.6.2 数组声明符”中,在相应的语义定义之后有一个 脚注

When several "array of" specifications are adjacent, a multidimensional array is declared.

几个相邻的“pointer of”规范的情况就不说了。有点“错误”。


1988 年的“参考手册”将 D1 和 D 调换了(!),但除此之外的措辞几乎完全相同。 (有 type-modifier 而不是 derived-declarator-type-list)。

例子类似:主要例子是int *ap[]:

Here ap[] plays the role of D1; a declaration "int ap[]" would ...

int **pp 一起,*pp 扮演那个角色。

作为记录,有三个答案被其作者删除,支持 C 标准的这方面很棘手的结论。我不相信其他当前答案正确地将示例源文本 (int * const * foo) 与标准段落中的符号 (T, D1类型限定符列表,等等)。

因此我断定这确实是标准中的一个错误。

我认为解决方法就是删除最后一句话,“对于列表中的每个类型限定符,ident 是一个如此限定的指针。” type-qualifier 列表中的任何限定词已正确并入前一句,并且 D 中的任何限定词已并入该声明符.所以这似乎只是一个多余的句子,可能是在某些编辑中无意中出现的。

这是使标准正确的另一种解释。

为了

int * const * foo

形式

* type-qualifier-listopt D

说明你例子中的 D 是 * foo

所以我认为 indent 应该被替换为 * foo 而不是 foo

所以标准说 * foo 是一个 const 指针。

这意味着 foo 是指向 const 指针的指针。