[英]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.