2016-06-10 40 views
9

據我瞭解,在C++中,內部函數參數列表中聲明一個類自動進入封閉範圍:類聲明

void f(struct A *p) {} 

void g() { A *p; f(p); } 

等同於:

struct A; 

void f(A *p) {} 

void g() { A *p; f(p); } 

什麼節在C++標準中指定了這種行爲?那麼C呢?

嗯,我猜C在這種情況下不遵循C++。 Visual Studio中不編譯這個代碼是C模式:

void g(struct A { int a; } a); 

struct A a;  // 'a' uses undefined struct 'A' 
+1

你的最後一個例子也不能用C++編譯。 – molbdnilo

+0

是的,我忘了注意C++不允許在函數參數列表裏面定義類的定義。我的意思是,在這種情況下,C沒有遵循C++,參數列表中的類聲明'泄漏'到函數聲明範圍中。 – igntec

回答

3

這是一個闡述型符。 C語言中的相關報價++ 14:

[basic.lookup.elab]/2: [...]如果詳細擬訂類型說明符由 的類鍵引入此查找沒有找到先前聲明類型名,或者如果闡述型說明符 出現在與聲明的形式:

class-key attribute-specifier-seqopt identifier ; 

è laborated-type-specifier是一個聲明,它引入了3.3.2中描述的類名。

這聲明的類名稱,象這樣:

[basic.scope.pdecl]/7:第一聲明的類的聲明的點闡述型說明符如下:

- [。 ..]

- 對於闡述型說明符的形式爲

class-key identifier 

如果詳細制定型說明符DECL說明符-SEQ或命名空間範圍定義的函數的參數聲明子句中使用的,識別符被聲明爲類 - 包含聲明的名稱空間中的名稱;否則,除作爲朋友聲明外,標識符在包含該聲明的最小名稱空間或塊範圍內聲明。

是因爲struct A闡述型符A以前尚未宣佈,A在包含聲明(在這種情況下,全局命名空間)的命名空間中聲明。