2009-11-12 65 views
5

檢查下面的代碼片段奇怪的C程序

struct st 
{ 
    struct st 
    { 
     int a ; 
     int b ; 
    } st; 

    int a1 ; 
} ; 

struct st obj ; 
struct st obj1 ; 

int main() 
{ 
    return obj.a1 + obj1.b ; 
} 

微軟的編譯器的Visual Studio 6.0成功地編譯程序。我對'struct st'的使用感到困惑。 obj和obj1的大小是多少?

+1

哪個struct st?這裏有4個。 – Naveen 2009-11-12 18:12:56

+0

無論printf(「%d%d \ n」,sizeof(obj),sizeof(obj1));返回... – 2009-11-12 18:13:24

+0

您發佈的內容在我能夠回憶的任何標準中都是無效的。相應地重新標記。 – 2009-11-12 18:21:32

回答

8

GCC給出

error: nested redefinition of ‘struct st’
error: ‘struct st’ has no member named ‘a1’

如果VC6編譯此,這很好,但是這是無效的。

如果你想知道obj的大小,那就是sizeof obj。我假設VC6只是將結構扁平化並分配了三個整數。

+1

順便說一句,VC9給出的錯誤:錯誤C3769:'st' :嵌套類不能和立即封閉的類名稱相同 – Naveen 2009-11-12 18:15:07

+0

@jleedev:我想MSVC會將它壓平 - 'obj1.st.st.st.st.a = 10'的確會影響'obj1.a'。 – Jacob 2009-11-12 18:16:39

+0

順便說一句什麼是正確的?編譯器是否應該發出錯誤或者應該成功編譯程序? – 2009-11-12 18:22:31

1

obj和obj1的大小是一樣的。 obj.a1 + obj1.b的值是未定義的,因爲未初始化您的代碼編譯器已損壞。如果那真的是BUILT,所有的投注都關閉。

NB:

該代碼得到了 '幫助' 從它的編譯器的實際工作有很多。 「幫助」我的意思是「我們有一個截止日期來推動它......它的錯誤分流時間,特別是在解析器所關心的地方!」

+0

說他們沒有被初始化是不正確的。 「全局」對象始終以C初始化爲零。當然,這一切都不重要,因爲代碼不可編譯。 – AnT 2009-11-12 18:30:26

+0

@AndreyT:如果真的編譯了,我想我們可以拋棄標準中關於事情如何被範圍對待的任何殘留。 – 2009-11-12 18:32:31

+0

@AndreyT:如果解析器很容易混淆......還有什麼呢?我的回答是試圖反映,而不是激怒VS球迷。 – 2009-11-12 18:35:53

0

這不是有效的C代碼。 C中沒有「類作用域」,從C語言的角度來看,struct st的兩個定義都定義了兩次相同的類型。這是非法的。

這只是C++代碼格式良好,但除此之外,程序只是計算並返回0.爲什麼它跳過所有這些箍來返回0超出了我。該程序也是C++的格式不正確。宣佈st類別爲st(即具有相同名稱)的成員是非法的。

1

只需快速瀏覽一下,就可以讓我認爲你已經定義了一個結構,聲明瞭struct類型的兩個變量。因此sizeof(obj)和sizeof(obj1)應該是相同的,因爲它們都是st類型的!不用說,同名的嵌套結構是非法的!並驚訝於它編譯。但請記住,自VC 6出來以後,C已經發生了變化(如果我的記憶能幫助我正確的話)。

+0

VS6在C99被批准之前就出來了,但這不是編譯無效代碼的原因,因爲沒有VS版本聲稱自己也實現了C99。我確信問題在於VS6不是你稱之爲「迂腐」的C編譯器...... – 2009-11-12 20:45:50