2009-11-12 18 views
5

は、MicrosoftのコンパイラのVisual Studio 6.0が正常にプログラムをコンパイル奇妙な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 ; 
} 

次のコードスニペットを確認してください。私は 'struct st'の使用と混同しています。 objとobj1のサイズは?

+1

struct st?ここには4つあります。 – Naveen

+0

printf( "%d%d \ n"、sizeof(obj)、sizeof(obj1));返信... –

+0

あなたが投稿した内容は、私が思い出すことのできる標準では有効ではありません。それに応じて再タグ付けされます。 –

答えて

8

GCCは

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

を与えるVC6がこれをコンパイルした場合、それは大丈夫ですが、これは無効です。

objのサイズを知りたい場合は、それはsizeof objです。私はVC6が構造を平坦化して3つの整数に割り当てたと仮定します。

+1

BTW、VC9エラーを返します:エラーC3769: :ネストされたクラスはすぐに囲むクラスと同じ名前を持つことはできません – Naveen

+0

@jleedev:私はMSVCがそれを平らにすると思います - 'obj1.st.st.st.st.a = 10'は' obj1.a'に影響します。 – Jacob

+0

何が正しいですか?コンパイラがエラーを発行するか、プログラムを正常にコンパイルする必要がありますか? –

1

objとobj1のサイズは同じです。どちらも初期化されていないので、obj.a1 + obj1.bの値は未定義ですおよびコードおよびコンパイラが壊れています。それが実際にビルドされている場合、すべてのベットはオフです。

NB:

このコードは、実際に動作するために、そのコンパイラから '助け' のLOTを得ました。 「助け」とは、「私たちにはこれを押し出す締め切りがあります。そのバナーの分類は、特にパーサーが関係する場所です」

+0

初期化されていないとは言えません。 「グローバル」オブジェクトは、常にC言語でゼロ初期化されます。もちろん、コードはコンパイル可能ではないので、これはすべての点の横にあります。 – AnT

+0

@AndreyT:それが実際にコンパイルされた場合、私は、物事がどのように扱われるかについて、標準の残りの部分を投げ捨てることができると思いますか? –

+0

@AndreyT:パーサーが簡単に混乱しているとすれば...他に何がありますか?私の答えは、VSのファンを怒らせることなくそれを反映させる試みでした。 –

0

これは有効なCコードではありません。 Cには「クラススコープ」はなく、C言語の観点からも、両方の定義で同じタイプのものが2回定義されています(struct st)。これは違法です。

これは、C++コードとしてのみ整形されていますが、プログラムが単純に計算して0を返している以外は、0を返すためにこれらのフープをジャンプします。プログラムはC++のように整形式ではありません。クラスstをクラスst(つまり、同じ名前)のメンバーとして宣言することは不正です。

1

これで一見したところでは、構造体を1つ定義し、構造体の2つの変数を宣言したと思います。したがって、sizeof(obj)とsizeof(obj1)は両方とも型stであるため同じでなければなりません!言うまでもなく、同じ名前の入れ子構造体は違法です!そして、それが集められたことに驚いた。しかし、覚えておいて、VC 6が出てから(私の記憶が正しいとすれば)Cが変わった。

+0

C99が批准される前にVS6が出てきましたが、これはVSのバージョンがC99を実装すると主張していないので、無効なコードをコンパイルする理由ではありません。私は問題がちょうどVS6があなたが "賢明な" Cコンパイラと呼ぶものではなかったと確信しています.... –