-1

C コンパイラから以下のテスト コードに対して間違った asm コードを取得しています。これは未定義の動作によるものですか?

void SimulatedTest(void)
{                                   
    if ( (a) || (b && c || d) == 1 )
    {
        i = 2;
    }
    else
    {
        i = 4;
    }
}

基準とは:

6.5.16 代入演算子

オペランドの評価順序は規定されていません。代入演算子の結果を変更したり、次のシーケンス ポイントの後にアクセスしようとした場合の動作は未定義です。

C 演算子の優先順位規則

  1. ()
  2. ==
  3. || &&

問題の場合: if ( (a) || (b && c || d) == 1 ) コンパイラは次の順序で式を評価し、間違ったコードを生成します

1.(b && c || d) -->R1

2.R1 == 1 -->R2

3.(a) || R2

ただし、コンパイラは以下の場合に正しいコードを生成します

ケース 1: . 関係「==」演算がない場合

if ( (a) || (b && c || d) )//compiler generates expected code

ケース 2:論理 OR 演算に括弧を追加する場合

if ( ((a) || (b && c || d)) == 1 )//compiler generates expected code

ケース 3:演算間に括弧を使用しない

if ( a || b && c || d == 1 )//compiler generates expected code

問題のケースが未定義の動作カテゴリに該当するかどうかを知りたいです。

よろしく、

マック

4

2 に答える 2

7

等値演算子==は、論理 or 演算子よりも優先順位が高くなり||ます。したがって、コンパイラは正しく、未定義の動作はありません。

評価は次と同じです。

a || ( ( b && c || d ) == 1 )
于 2016-07-29T09:59:48.993 に答える
0

これ:

 if ( (a) || (b && c || d) == 1 )

の結果を整数と比較していますが||、これは決してやりたいことではありません。

人々が期待するものとは限らない論理演算子の優先順位を考えると、一般に、読みやすくするために括弧を入れるのが最も安全です。

 if ( (a) || ((b && c) || d) == 1 )

また

 if ( (a) || (b && (c || d)) == 1 )

&&またはに対処する||

== が何と比較されると予想するかによって異なります (本当にやりたいのであれば、私は疑います)

 if ( (a) || ((b && c || d) == 1) )

また

 if ( ((a) || (b && c || d)) == 1 )

しかし、コンパイラは正しくコンパイルしています。人間の心に何が起こっているのかは、それほど明白ではありません。

于 2016-07-29T11:11:19.860 に答える