2017-07-04 12 views
-2

私はCプログラミングの知識に何が起こったのか理解しようとしています。のは(初期化されていないポインタデリファレンス)クラシカルな問題を見てみましょう:なぜClangは初期化されていないポインタの逆参照をサポートしていますか

int main(void) { 
    char *p; 
    *p = 'a'; 
    printf("%c\n", *p); 
    return 0; 
} 

これは明らかに間違っています!私はそれを知っている。しかし、MacOS 10.12でLLVM Clang 8.1.0をコンパイラとして実装した場合、初期化されていないポインタの検出に失敗するだけでなく、何も間違っていないかのように画面に文字「a」が表示されます。少なくとも私は「セグメンテーションフォルト」のようなものを期待しています。

あなたの思考を保持し、私と一緒に以下のコードを参照する瞬間を負担してください:

int main(void) { 
    int i; 
    char **strPtr; 
    char *string = "Hello, world!"; 

    *strPtr = string; 

    printf("%s", *strPtr); 
    return 0; 
} 

今回、私が最初にセグメンテーションフォールトを成功裏に検出されたGCC-4.8.5を使用してコードを実行しましたコード。私の残念なことに、文字列 "こんにちは、世界!"あたかも何も間違っていないかのようにコードを実行した後、画面に現れました。

strPtrもポインタ(ポインタへのポインタ)であるため、逆参照してstrPtrに値を代入すると、最初のコードと同じフォルトを実行してはいけないのでしょうか?

+2

このようなことについて警告する( '-Wall')、そのような警告エラー(' -Werror')を考慮する必要があることをあなたの仲間に伝えます。換言すれば、例えば'clang -Wall -Werror source.c -oバイナリ'。 –

+0

あなたのポインタは初期化されていません。そしてclangを含むどんな神のコンパイラも、無意味な変換について警告します。それを無視する(または推奨された警告を有効にしない)場合、コンパイラの不具合ではありません – Olaf

+0

"しかし、結果を表示" - どの結果ですか?そのコードは意味をなさないが、未定義の動作を呼び出します。 – Olaf

答えて

3

サポートです。コンパイラがあなたが何をしているのかをあなたが知っていると仮定しているだけです。

非初期化ポインタの逆参照時の動作は、未定義です。

動作しているように見えるのは、未定義の動作の兆候です。

古い格言を思い出してください。Cは自分の足で自分を撃つことができます。

関連する問題