8

以下では:

printf("Example%s\n",NULL);
printf("%s\n",NULL);

次のように出力を取得します。

Example(null)
Segmentation Fault

GDBでバックトレースを試したところ、にprintf()変換されていることが示されていputs()ます。しかし、なぜこれが起こるのか理解できないようです。

ところで、私はこの記事を見つけましたが、それでも意味がないようです。

4

1 に答える 1

15

標準では、 with指定子NULLへの引数としてポインターを渡すことは未定義の動作1 (つまり、何でも起こり得る) であると規定されているため、どちらの動作も正当です。printf%s

最初のケースでは、標準ライブラリ (特にprintfコード) が印刷することであなたに好意を示しています(null)

2 番目のケースでは、代わりに、オプティマイザーは、プログラムの「観察可能な動作」を変更せずに (より効率的な) yourprintfを a に置き換えることができることを理解し、それを置き換えます。putsしかし、には のチェック コードがputs含まれていないため、セグメンテーション エラーが発生します。NULLprintf


  1. C99、§7.19.6.1、¶8:

    引数は、文字型の配列の最初の要素へのポインターでなければなりません。

    ¶9:

    対応する変換指定に対して正しい型でない引数がある場合、動作は未定義です。

    NULLは「文字型の配列の最初の要素へのポインタではない」ため、この最後のケースに当てはまります。

于 2012-04-10T21:13:54.650 に答える