ホームページ >バックエンド開発 >C++ >C では `i = i` は常に未定義の動作ですか?

C では `i = i` は常に未定義の動作ですか?

Patricia Arquette
Patricia Arquetteオリジナル
2024-12-07 03:00:11936ブラウズ

Is `i  =   i` Always Undefined Behavior in C  ?

未定義の動作とシーケンス ポイントの再検討

組み込み型の未定義の動作

前回の記事「未定義の動作とシーケンス ポイント」では、に関連する潜在的な未定義の動作について説明しました。式:

i += ++i;

i が組み込み型の場合、オブジェクト i は連続するシーケンス ポイント間で 2 回変更されるため、この式は未定義の動作を呼び出します。

ユーザー定義型の未定義の動作

ただし、i がユーザー定義型 (定義された Index クラスなど) の場合以下:

class Index
{
    int state;

    public:
        Index(int s) : state(s) {}
        Index& operator++()
        {
            state++;
            return *this;
        }
        Index& operator+=(const Index & index)
        {
            state+= index.state;
            return *this;
        }
        operator int()
        {
            return state;
        }
        Index & add(const Index & index)
        {
            state += index.state;
            return *this;
        }
        Index & inc()
        {
            state++;
            return *this;
        }
};

式 i = i はまだ未定義の動作を呼び出しますか?

オーバーロードされた演算子の適切に定義された動作

驚くべきことに、いいえです。ユーザー定義型 i の式 i = i は、オーバーロードされた演算子が C の関数とみなされるため、未定義の動作を引き起こしません。 C ISO 標準のセクション 1.9.17 によると:

関数を呼び出すとき (関数がインラインであるかどうかに関係なく)、すべての関数引数の評価後にシーケンス ポイントがあります...

したがって、演算子および演算子 = 関数の呼び出しにはシーケンス ポイントが導入され、未定義の動作が防止されます。

a[ i] = の未定義の動作i

式 a[ i] = i は、 a がオーバーロードされた添字演算子を持つユーザー定義型である場合にも、 i 式の評価後にシーケンス ポイントを持つ関数呼び出しとみなされるため、適切に定義されています。 .

i の明確に定義された動作

C 03 では、式 i は事実上同等であるため、明確に定義されています。 to:

((i.operator++()).operator++()).operator++();

各関数呼び出しでシーケンス ポイントが導入され、式が明確に定義されます。

以上がC では `i = i` は常に未定義の動作ですか?の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。