2017-12-22 2 views
0

これは本の演習です。問題はこのコードの出力です。プリプロセッサ後のCコード

このコードは、常に "N is undefined"を表示しますが、その理由はわかりません。コマンド "#undef N"は、関数fの後にあります。次に、出力が常に "N is undefined"の理由は何ですか?

#define N 100 
void f(void); 

int main(void) 
{ 
    f(); 
    #ifdef N 
     #undef N 
    #endif 
    return 0; 
} 

void f(void) 
{ 
    #if defined(N) 
     printf("N is %d\n", N); 
    #else 
    printf("N is undefined\n"); 
    #endif 
} 

答えて

0

プリプロセッサの命令は「物理的な」順序で実行されるため、行の後に改行されます。

実際のコンパイルの前に、コンパイラのプレーンなCコードのみでコードをクリアするようなことを考えてみましょう。

1

この練習のポイントは、プリプロセッサの制御フローがプログラムの制御フローとは完全に独立していることを示すことです。

#if/#undefディレクティブは、プログラムのテキストに表示される順序で処理されます。コンパイル時に一度だけ処理されます。プリプロセッサ変数を定義または定義解除する決定を実行時に再考することはできません。

だから、main#if/#undef行の前にfが実行されるということは無関係です。このプログラムの出力は、fの位置にmainの前に移動することによってのみ変更できます。

1

コンパイラを-Eフラグ(少なくともgcc用)で実行すると、実際にコンパイルしているコードが表示されます。

プリプロセッサがコードの実行に従わないことがわかります。プリプロセッサはファイル内に表示されている順序でアクションを実行します。

コンパイラは結果のコードを受け取り、には、Nが定義されていないことを示すprintfという1つの呼び出しがあります。

1

Cプリプロセッサは、コードを1行ずつ実行します。そのため、関数呼び出しのためにf()の後に#undefが発生すると仮定するのは間違いです。代わりに、関数f()の定義の前に発生します。

これを理解するには、プリプロセッサ(行ごと)と制御フロー(関数呼び出しに続く)を区別する必要があります。

関連する問題