Share via


コンパイラの警告 (レベル 4) C4868

'file(line_number)' コンパイラでは、中かっこで囲まれた初期化子リストの評価順序を左から右方向に設定できない場合があります

中かっこで囲まれた初期化子リストの要素は、左から右の順序で評価されます。 コンパイラでこの順序を保証できない 2 つのケースがあります。1 番目は、一部の要素が値渡しで渡されるオブジェクトである場合です。2 番目は、/clr を使用してコンパイルし、一部の要素がオブジェクトのフィールドであるか配列要素である場合です。 左から右への評価を保証できない場合、コンパイラは警告 C4868 を出力します。

この警告は、Visual Studio 2015 Update 2 で行われたコンパイラの準拠作業の結果として生成される可能性があります。 Visual Studio 2015 Update 2 よりも前にコンパイルされたコードは現在、C4868 を生成する可能性があります。

既定では、この警告はオフに設定されています。 /Wall を使用して、この警告をアクティブにします。

この警告を解決するには、まず、初期化子リストの要素を左から右に評価することが必要かどうかを検討します (要素の評価によって順序に依存した副作用が生じる場合など)。 多くの場合、要素が評価される順序により目に見える影響が生じることはありません。

評価の順序が左から右であることが必要な場合は、代わりに const 参照によって要素を渡すことが可能かどうかを検討してください。 このような変更により、次のコード サンプルにおける警告がなくなります。

この例では C4868 が生成され、その修正方法を示しています。

// C4868.cpp
// compile with: /c /Wall
#include <cstdio>

class HasCopyConstructor
{
public:
    int x;

    HasCopyConstructor(int x): x(x) {}

    HasCopyConstructor(const HasCopyConstructor& h): x(h.x)
    {
        printf("Constructing %d\n", h.x);
    }
};

class TripWarning4868
{
public:
    // note that taking "HasCopyConstructor" parameters by-value will trigger copy-construction.
    TripWarning4868(HasCopyConstructor a, HasCopyConstructor b) {}

    // This variation will not trigger the warning:
    // TripWarning4868(const HasCopyConstructor& a, const HasCopyConstructor& b) {}
};

int main()
{
    HasCopyConstructor a{1};
    HasCopyConstructor b{2};

    // the warning will indicate the below line, the usage of the braced initializer list.
    TripWarning4868 warningOnThisLine{a, b};
};