void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
私は最近、シーケンス ポイントについて読み始めましたが、上記のコード サンプルが適切かどうかわかりません。演算子がシーケンス ポイントを導入することは知っている&&
ので、式 z = x && y && ++z の動作についてよくわかりません。だれか正解を教えてください。
void main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;//is this fine?
}
私は最近、シーケンス ポイントについて読み始めましたが、上記のコード サンプルが適切かどうかわかりません。演算子がシーケンス ポイントを導入することは知っている&&
ので、式 z = x && y && ++z の動作についてよくわかりません。だれか正解を教えてください。
C++ 03 で。
void main(void)
{
int x,y,z;
x=y=z=1; // Seq1 at ;
z = x && y && ++z;//is this fine? // Seq2 at ;
}
注意: 演算子 && にはシーケンス ポイントがありますが、この例では関係ありません。
罰金!。一般に、そうかもしれないし、そうでないかもしれない。x と y の値に依存します。あなたの特定のケースでは、それは問題ありません。このコードには、undefined behaviorと呼ばれるものが含まれる可能性があります。
z++ が評価される場合 ( x と y が 1 であるため、例のように)、スカラー変数 'z' は、2 つのシーケンス ポイント Seq1 と Seq2 の間の式で複数回変更されます (以下を参照)。代入演算子はシーケンス ポイントを導入しないことに注意することが重要です。
$5/4- 「注記がある場合を除き、個々の演算子のオペランドと個々の式の部分式の評価の順序、および副作用が発生する順序は指定されていません.53)前と次のシーケンスポイントの間で、スカラーオブジェクトは格納された値は、式の評価によって最大 1 回変更されます. さらに、前の値は、格納される値を決定するためにのみアクセスされるものとします.この段落の要件は、完全な式の部分式の許容される順序ごとに満たされるものとします.それ以外の場合、動作は未定義です。」
C++0x の場合
@litb が参照する議論の詳細を私自身が理解したら、更新します。今のところ、私はちょうどそれを打っています
しかし、C++0X では、私が理解しているように、シーケンス ポイントの概念はありません。この式は問題なく、未定義の動作を引き起こしません。これは、'z' に対する ++ の効果が、'z' に対する代入の副作用の前に順序付けられるためです。
$1.9/15- 「注記がある場合を除き、個々の演算子のオペランドおよび個々の式の部分式の評価は順序付けされていません。サブ式は、異なる評価で一貫して実行される必要はありません. —エンドノート] 演算子のオペランドの値計算は、演算子の結果の値計算の前に順序付けられます.スカラーオブジェクトに対する副作用が、互いに相対的に順序付けされていない場合同じスカラー オブジェクトまたは同じスカラー オブジェクトの値を使用した値の計算に対する副作用の場合、動作は未定義です。
$3.9/9 - 「算術型 (3.9.1)、列挙型、ポインター型、メンバー型へのポインター (3.9.2)、std::nullptr_t、およびこれらの型の cv 修飾バージョン (3.9.3) をまとめて呼びます。スカラー型。」
式「z = z++;」に注意してください。ここで、z はスカラー変数であり、代入演算子と後置 operator++ による 'z' への副作用は順序付けされていません (どちらも順序付けされていません)。
この投稿を元のバージョンから改良するために貴重な情報を提供してくれた @Prasoon に感謝します
その行が問題ないかどうかを知る簡単な方法は、コンパイラにそれをチェックさせることです。たとえば、gcc には 、シーケンス ポイントがないために未定義の動作があるかどうかをチェックするための-Wsequence-point
オプション(によって有効化) があります。-Wall
あなたのプログラム
int main(void)
{
int x,y,z;
x=y=z=1;
z = x && y && ++z;/*is this fine?*/
return 0;
}
次の警告が生成されます。
xc: 関数 'main' 内: xc:6:5: 警告: 'z' の操作は未定義の可能性があります
はい、コンパイルされます。
しかし、論理的なバグについて質問している場合:
1)&&
演算子は、最終結果が確実にわかっているときに式の評価を終了できるため、シーケンス ポイントを導入します (この場合、値は評価0
を終了できます)。ゼロ。++z
x
y
2)&&
演算子は論理演算子であるため、結果は常に 0 または 1 になります。