2011-02-08 9 views
14

私は次のコードを実行すると:strcmpの行動

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    int p = 0; 

    p = strcmp(NULL,"foo"); 

    return 0; 
} 

を私はセグメンテーションフォールトを取得します。エコー$?しかし、私が走るとき

#include <stdio.h> 

int main(int argc, char *argv[]) 
{ 
    int p = 0; 

    strcmp(NULL,"foo"); // Note removed assignment 

    return 0; 
} 

私はセグメンテーションフォールトを取得しません。誰かが光を投げてくれますか?何をやっている

> gcc --version 
gcc (GCC) 3.4.6 20060404 (Red Hat 3.4.6-8) 

答えて

30

コンパイル時に最適化オプションを使用している可能性があります。 2番目のスニペットのstrcmp()の結果は無視されるため、コンパイラはこの関数呼び出しを削除します。これがプログラムがクラッシュしない理由です。この呼び出しは、strcmp()が組み込み関数であるためにのみ削除できます。コンパイラは、この関数に副作用がないことを認識しています。

+0

まあ、最適化を有効にするためのコンパイラ設定はしていませんが、自動的に行います。あなたは一所懸命でした。 –

+2

gccは、最適化を有効にしなくても機能するSSAを実行します。 SSAはデッドコードを削除できます。 http://en.wikipedia.org/wiki/Static_single_assignment_form –

3

が定義されていない:

は、ここに私のgccのinfoです。 strcmpには、NULLで終了する文字列への有効なポインタが必要です。

NULLは、NULLで終了する文字列へのポインタではありません。あなたがする必要があり

6

  • は、適切なヘッダを含める、または手動で関数を宣言します。 strcmp()の場合は<string.h>が必要です。
  • 無効なポインタ(NULLなど)をstrcmp()に渡すことはできません。そのポインタは保護されていないため、ポインタを逆参照し、プログラムで未定義の動作を引き起こします。
+6

OPはNULLが無効であることを知っていますが、なぜ2つのケースが異なるかを尋ねています。 –