簡體   English   中英

C99(及更高版本)7.1.3 保留標識符是否缺少“外部”?

[英]Does C99 (and later) 7.1.3 Reserved identifiers miss "external"?

C89, 4.1.2 標准標頭(添加了重點):

所有以下划線開頭的外部標識符都是保留的。

C99(及更高版本),7.1.3 保留標識符,1(添加了重點):

所有以下划線開頭的標識符始終保留用作文件 scope 中普通名稱空間和標記名稱空間中的標識符。

C 的基本原理,7.1.3 保留標識符,25(添加了強調):

還為實施者保留的是所有以下划線開頭的外部標識符,以及所有其他以下划線開頭后跟大寫字母或下划線的標識符。

因此,根據 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 保留標識符中缺少“外部”:“所有外部標識符……”?

桌子:

                                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(及更高版本)保留更多(如果表格正確)。 額外:為了什么目的?

C99(及更高版本)7.1.3 保留標識符是否缺少“外部”?

顯然,C99 和 C 的每個后續版本,直到並包括當前最新的 C17,都在您詢問的條款中省略了“外部”資格。 這不一定構成其文本中的缺陷。

因此,根據 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 相矛盾。

是的,這些聲明出現在文件 scope 中,分別聲明了沒有鏈接和內部鏈接的_t_f 它們不是外部標識符(盡管它們是在外部聲明中聲明的),因此 C89 不保留它們供該用途使用。 另一方面,C99 及更高版本保留它們供該用途使用。

“矛盾”對於這種差異來說太強烈了。 是的,C99 保留了一些 C89 沒有的標識符用法(反之亦然)。 這不是兩者之間唯一的向后不兼容。 C99“取消並取代”了C89,因此前者無需與后者的所有細節保持一致。

至於理由,是的,它解釋了保留的C89版本,而不是C99形式。 我認為是理由中的一個缺陷,畢竟這不是規范性的。

這是否意味着 C99(及更高版本)在 7.1.3 保留標識符中缺少“外部”:“所有外部標識符……”?

我認為沒有理由斷定 C99 和后來的條款中省略“外部”代表編輯錯誤。 事實上,我將周圍文本的相應更改作為更改是有意更改的證據。 特別是,C89 文本繼續“所有其他以下划線和大寫字母或另一個下划線開頭的標識符”(強調已添加),而 C99 和更高版本也刪除了“其他”。 據我所知,C99 打算保留比 C89 更多的標識符使用。

但是這里可能存在一個缺陷,即 C89 保留了一些 C99 沒有但可能打算使用的標識符使用。 這些是塊 scope 處的外部標識符,它們以下划線開頭,但沒有緊跟大寫字母或另一個下划線。 例子:

int f(void) {
    extern int _var;
    extern int _func(int);

    // ...
}

_var_func的這些用法在 C89 中保留,但在 C99 及更高版本中不保留。 符合 C 的代碼無法提供鏈接到這些標識符的定義,因為規范的所有版本中的標識符保留都不允許這樣做,但它們可能與實現定義的外部標識符發生沖突。

我認為 C89 和 C99 中的規則是相同的(即保留您的示例用法),但措辭已得到改進。 釋義:

  • 舊:“保留外部標識符 [描述]”。
  • 新:“標識符 [描述] 保留用於外部聲明”。

該標准甚至沒有定義術語“外部標識符”; 也許這是改變措辭的動機之一。

如果我們把“外部標識符”理解為“由外部聲明聲明的標識符”,那么規則是一樣的。


注意:外部聲明是指“具有文件范圍的聲明”(C11 6.9/4); 這經常與“帶有外部鏈接的標識符聲明”相混淆。

C89 標准確實使用了特定文本“帶有外部鏈接的標識符”(例如 A.6.3.2),所以我認為“外部標識符”不應該表示“帶有外部鏈接的標識符”。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM