2013-04-19 12 views
9

私は最終的に、以下のコードに類似したタイプミスをトレースします。 コンパイラはこれを(デフォルトではオプションで)検出してはいけませんか?コンパイラが変数を自分自身で初期化できるのはなぜですか?

#include <stdio.h> 

int main() 
{ 
    int c = c; 
    return printf("%d\n", c); 
} 


$ gcc --version   
gcc (Ubuntu 4.4.3-4ubuntu5.1) 4.4.3 
+10

初期化を使用して未定義の動作を呼び出します。コンパイラーは問題を診断する必要もなく、問題が発生したときに何を行うかを定義する必要もありません。 –

+8

私はあなたがこれをしているときに警告を出すときに(GCCの-Wall)、あなたに警告する私の左靴を賭けるだろう。警告を無視しないでください;-) – nothrow

+0

vcが検出されました。 – BLUEPIXY

答えて

7

私はなぜそれがコンパイルされないのかわかりません。定義は初期化の前に行われます。もちろん、この初期設定は無意味ですが、コンパイラの立場からはうまくいきません。

Cには、C#などのより現代的な言語と同じ種類の保護機能はありません。 C#コンパイラは、割り当てられていない変数を使用しているというエラーを表示します。 Cは気にしない。それはあなたからあなたを守るものではありません。

int c; 
c = c; 

がコンパイルされます

+5

この初期化ではなく、割り当てです。 –

+5

また、 'int x = initialize_and_register(&x)'のようにアドレスを取ることができるので、変数の初期化のために変数を参照することは*有用*です。 (そのような呼び出しは、通常、マクロにパッケージ化されます。) – user4815162342

+0

@ user4815162342 true、それは明らかに意味があります。私は自分の言葉をよく選んだはずです:( – evanmcdonnal

-3

場合int c = c;がコンパイルされませんなぜ、私は表示されません。

+7

2つはうっすらと似ていますが、実際はかなり異なっています: 'int c = ...'は代入ではなく初期化です。たとえば、 'int c [] = {1,2,3};'は動作しますが、 '{1,2,3} 'は代入のコンテキストでは有効ではありません。 – delnan

5

変数を独自のイニシャライザで使用することは完全に正当です。値が難しい問題で初期化されていない使用されている場合、診断、一般的に

#include <stdio.h> 
struct node { struct node *prev, *next; int value; }; 
int main() { 
    struct node l[] = {{0, l + 1, 42}, {l, l + 2, 5}, {l, 0, 99}}; 
    for (struct node *n = l; n; n = n->next) 
     printf("%d\n", n->value); 
    return 0; 
} 

;:リンクリストを考えてみましょういくつかのコンパイラはそれを検出することができますが、それが起こることを要求するのは理にかなっていません。

+0

定義されていない動作はどのように正当ですか? – rubenvb

+8

この文脈では、 'l'はポインタ'&[0] 'に崩壊するので、これ自体で変数を初期化するのではなく、それ自身を指すポインタです。 –

+0

これは定義されていますか? – this

関連する問題