C99(及更高版本)7.1.3 保留标识符是否缺少 "external"?
Does C99 (and later) 7.1.3 Reserved identifiers miss "external"?
C89, 4.1.2 Standard headers(强调已加):
All external identifiers that begin with an underscore are reserved.
C99 (and later), 7.1.3 Reserved identifiers, 1(强调已加):
All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
C 的基本原理,7.1.3 保留标识符,25(强调已添加):
Also reserved for the implementor are all external identifiers beginning with an underscore, and all other identifiers beginning with an underscore followed by a capital letter or an underscore.
因此,根据 C99(及更高版本),在:
typedef int _t; // non-reserved in C89, reserved in C99 (and later)
static int _f(int x); // non-reserved in C89, reserved in C99 (and later)
(在文件范围内声明)_t
和 _f
被保留,这与 Rationale 和 C89 相矛盾。
这是否意味着 C99(及更高版本)在 7.1.3 保留标识符中缺少“外部”:“所有 外部 标识符...”?
table:
is _x reserved ?
C89 C99 (and later)
scope - linkage
function - external n/a n/a
function - internal n/a n/a
function - none no no
file - external yes yes**
file - internal no yes**
file - none no yes**
block - external yes no*
block - internal n/a n/a
block - none no no
function prototype - external n/a n/a
function prototype - internal n/a n/a
function prototype - none no no
其中 *
是一个可能的缺陷,请参阅 并且 **
是“在普通名称空间和标记名称空间中”(C11,7.1.3 保留标识符,1) .
在这里我们看到 C99(及更高版本)保留更多(如果 table 是正确的)。额外:为了什么目的?
我认为 C89 和 C99 中的规则相同(即保留您的示例用法),但措辞已得到改进。转述:
- 旧:“保留外部标识符[描述]”。
- 新:“标识符 [description] 保留用于外部声明”。
标准甚至没有定义术语“外部标识符”;也许这是措辞改变的动机之一。
如果我们把“外部标识符”理解为“由外部声明声明的标识符”,那么规则是一样的。
注意:外部声明表示“具有文件作用域的声明”(C11 6.9/4);这经常与“带有外部链接的标识符声明”相混淆。
C89 标准确实使用了特定文本“带有外部链接的标识符”(例如 A.6.3.2),所以我认为“外部标识符”不应该表示“带有外部链接的标识符” .
Does C99 (and later) 7.1.3 Reserved identifiers miss "external"?
很明显,C99 和 C 的每个后续版本,直到并包括当前最新的 C17,省略 您所询问的条款中的“外部”限定。这不一定构成他们文本中的缺陷。
So, per C99 (and later), in:
typedef int _t; // non-reserved in C89, reserved in C99 (and later)
static int _f(int x); // non-reserved in C89, reserved in C99 (and later)
(declared at file scope) the _t
and _f
are reserved, which contradicts
with Rationale and with C89.
是的,那些出现在文件范围内的声明分别声明了没有 linkage 和内部 linkage 的 _t
和 _f
。它们不是外部标识符(尽管它们在 外部声明 中声明),因此 C89 不保留它们用于该用途。另一方面,C99 及更高版本 do 保留它们供该用途使用。
“矛盾”对于这种差异来说太强烈了。是的,C99 保留了一些 C89 没有的标识符用法(反之亦然)。这不是两者之间唯一的向后不兼容。 C99“取消并取代”了C89,因此前者不需要与后者的所有细节一致。
至于原理,是的,解释的是C89版本的保留,不是C99的形式。我认为那个是理由上的缺陷,毕竟不规范。
Does it mean that C99 (and later) misses "external" in 7.1.3 Reserved identifiers: "All external identifiers that ..."?
我认为没有理由断定 C99 及更高版本中该条款中省略“外部”代表编辑错误。事实上,我将周围文本的相应更改作为更改是有意更改的证据。特别是,C89 文本继续“所有 other 标识符以下划线和 upper-case 字母或另一个下划线开头”(强调已添加),而 C99 和更高版本删除“其他”也是如此。据我所知,C99 打算保留比 C89 更多的标识符使用。
但是这里 是 一个可能的缺陷,因为 C89 保留了一些标识符使用,而 C99 没有,但可能打算这样做。这些是外部标识符 在块范围 下划线开头,不紧跟大写字母或另一个下划线。示例:
int f(void) {
extern int _var;
extern int _func(int);
// ...
}
_var
和 _func
的那些用法在 C89 中保留,但在 C99 及更高版本中不保留。符合标准的 C 代码无法为这些标识符提供 link 的定义,因为规范的所有版本中的标识符保留都不允许这样做,但它们可能与实现定义的外部标识符发生冲突。
C89, 4.1.2 Standard headers(强调已加):
All external identifiers that begin with an underscore are reserved.
C99 (and later), 7.1.3 Reserved identifiers, 1(强调已加):
All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.
C 的基本原理,7.1.3 保留标识符,25(强调已添加):
Also reserved for the implementor are all external identifiers beginning with an underscore, and all other identifiers beginning with an underscore followed by a capital letter or an underscore.
因此,根据 C99(及更高版本),在:
typedef int _t; // non-reserved in C89, reserved in C99 (and later)
static int _f(int x); // non-reserved in C89, reserved in C99 (and later)
(在文件范围内声明)_t
和 _f
被保留,这与 Rationale 和 C89 相矛盾。
这是否意味着 C99(及更高版本)在 7.1.3 保留标识符中缺少“外部”:“所有 外部 标识符...”?
table:
is _x reserved ?
C89 C99 (and later)
scope - linkage
function - external n/a n/a
function - internal n/a n/a
function - none no no
file - external yes yes**
file - internal no yes**
file - none no yes**
block - external yes no*
block - internal n/a n/a
block - none no no
function prototype - external n/a n/a
function prototype - internal n/a n/a
function prototype - none no no
其中 *
是一个可能的缺陷,请参阅 **
是“在普通名称空间和标记名称空间中”(C11,7.1.3 保留标识符,1) .
在这里我们看到 C99(及更高版本)保留更多(如果 table 是正确的)。额外:为了什么目的?
我认为 C89 和 C99 中的规则相同(即保留您的示例用法),但措辞已得到改进。转述:
- 旧:“保留外部标识符[描述]”。
- 新:“标识符 [description] 保留用于外部声明”。
标准甚至没有定义术语“外部标识符”;也许这是措辞改变的动机之一。
如果我们把“外部标识符”理解为“由外部声明声明的标识符”,那么规则是一样的。
注意:外部声明表示“具有文件作用域的声明”(C11 6.9/4);这经常与“带有外部链接的标识符声明”相混淆。
C89 标准确实使用了特定文本“带有外部链接的标识符”(例如 A.6.3.2),所以我认为“外部标识符”不应该表示“带有外部链接的标识符” .
Does C99 (and later) 7.1.3 Reserved identifiers miss "external"?
很明显,C99 和 C 的每个后续版本,直到并包括当前最新的 C17,省略 您所询问的条款中的“外部”限定。这不一定构成他们文本中的缺陷。
So, per C99 (and later), in:
typedef int _t; // non-reserved in C89, reserved in C99 (and later) static int _f(int x); // non-reserved in C89, reserved in C99 (and later)
(declared at file scope) the
_t
and_f
are reserved, which contradicts with Rationale and with C89.
是的,那些出现在文件范围内的声明分别声明了没有 linkage 和内部 linkage 的 _t
和 _f
。它们不是外部标识符(尽管它们在 外部声明 中声明),因此 C89 不保留它们用于该用途。另一方面,C99 及更高版本 do 保留它们供该用途使用。
“矛盾”对于这种差异来说太强烈了。是的,C99 保留了一些 C89 没有的标识符用法(反之亦然)。这不是两者之间唯一的向后不兼容。 C99“取消并取代”了C89,因此前者不需要与后者的所有细节一致。
至于原理,是的,解释的是C89版本的保留,不是C99的形式。我认为那个是理由上的缺陷,毕竟不规范。
Does it mean that C99 (and later) misses "external" in 7.1.3 Reserved identifiers: "All external identifiers that ..."?
我认为没有理由断定 C99 及更高版本中该条款中省略“外部”代表编辑错误。事实上,我将周围文本的相应更改作为更改是有意更改的证据。特别是,C89 文本继续“所有 other 标识符以下划线和 upper-case 字母或另一个下划线开头”(强调已添加),而 C99 和更高版本删除“其他”也是如此。据我所知,C99 打算保留比 C89 更多的标识符使用。
但是这里 是 一个可能的缺陷,因为 C89 保留了一些标识符使用,而 C99 没有,但可能打算这样做。这些是外部标识符 在块范围 下划线开头,不紧跟大写字母或另一个下划线。示例:
int f(void) {
extern int _var;
extern int _func(int);
// ...
}
_var
和 _func
的那些用法在 C89 中保留,但在 C99 及更高版本中不保留。符合标准的 C 代码无法为这些标识符提供 link 的定义,因为规范的所有版本中的标识符保留都不允许这样做,但它们可能与实现定义的外部标识符发生冲突。