2

私は小さいコードを持っていますが、出力がそのようなものである理由を理解できませんでした。
ここにあります

#include <stdio.h>

int f(int i, int j, int k);

int main(int argc, char const *argv[])  
{  
    int a;   
    printf("enter a\n");  
    scanf("%d",&a);  
    f(a,a++,a++);  
    printf("%d \n",a );  
    return 0;  
}  

int f(int i, int j, int k)  
{  
    printf("function arguments \n");  
    printf("%d %d %d\n",i,j,k );  
}   

入力:4
出力:6 5 4

4

2 に答える 2

4

マークされた重複で受け入れられた回答は正しくありません。


f(a,a++,a++); 

未定義の動作を引き起こしますaシーケンスポイントを介さずに引数を変更しようとします。また、関数の引数の評価の順序は指定されていないことに注意することが重要です。かもね:

  • 左から右または
  • 右から左または
  • コンパイラが選択する魔法の順序。

GCCを使用している場合は、警告フラグ-wsequence-pointを使用して、シーケンスポイントに関連する未定義の動作を警告できます。


GCCでは、最も厳しい警告レベルでプログラムをコンパイルすると、コンパイラーは次の診断を提供します。

prog.c:10:18:エラー:「a」の操作が未定義の可能性があります[-Werror = sequence-point]
prog.c:10:18:エラー:「a」の操作が未定義の可能性があります[-Werror = sequence-点]


参照:

C99標準§6.5.2.2:
パラ10:

関数指定子、実際の引数、および実際の引数内の部分式の評価の順序は指定されていませんが、実際の呼び出しの前にシーケンスポイントがあります。

引用符は、実際の関数呼び出しの前にシーケンスポイントがあることを示しているだけであり、部分式引数の評価の間にシーケンスポイントがあることを意味するものではないことに注意してください。

于 2013-02-22T15:22:10.147 に答える
1

f(a,a++,a++);次の理由により、未定義の動作のようです。

スカラーオブジェクトの副作用が、同じスカラーオブジェクトの別の副作用、または同じスカラーオブジェクトの値を使用した値の計算に比べて順序付けされていない場合、動作は定義されていません。式の部分式に許容される順序が複数ある場合、そのような順序付けられていない副作用がいずれかの順序で発生した場合の動作は定義されていません。

未定義の動作を使用する場合、C標準からの要件はありません。

于 2013-02-22T15:22:55.623 に答える