web-dev-qa-db-ja.com

C ++ 14とC ++ 17の違い: `* p ++ = * p`

いくつかのコードを書いているときに、設定した値が正しく設定されていないという問題に遭遇しました。私は最終的に原因の行を見つけ、周りをテストしているときに、C++ 14とC++ 17では動作が異なることがわかりました。コードは次のとおりです。

#include <stdio.h>
#include <cstdint>
#include <cstring>

int main()
{
    uint8_t *p = new uint8_t[3];
    memset(p, 0x00, 1);
    p++;
    memset(p, 0xF0, 1);
    p++;
    memset(p, 0xFF, 1);
    p--;
    p--;

    // This line in particular
    *p++ = *p;

    *p++ = 0x0F;

    p--;
    p--;

    printf("Position 0 has value %u\n", *p);
    p++;
    printf("Position 1 has value %u\n", *p);
    p++;
    printf("Position 2 has value %u\n", *p);

    return 0;
}

C++ 14では、次のように出力されます。

Position 0 has value 240
Position 1 has value 15
Position 2 has value 255

そしてC++ 17では次のように表示されます:

Position 0 has value 0
Position 1 has value 15
Position 2 has value 255

C++のバージョンによって動作が異なる理由を知りたいです。 C++ 14では、割り当ての*pの右側が++の後に評価されるように見えます。この変更はありましたか?また、++が優先される場合、代入演算子の左側の逆参照の前になぜそれが発生しないのですか?

36
ApplePearPerson

(ポストインクリメントを介した)変数の読み取りと書き込みは、=はシーケンスポイントを導入しませんでした。 C++ 14ではどちらかの動作(または何も起こらない、または爆発)を受け取る可能性があります。

現在、この場合に定義されている順序付け順序があります であり、C++ 17の結果は信頼できます。

それはまだ悪いですが、書かれるべきではない不明確なコード!