Compiler Warning (level 4) C4868

'file(line_number)' compiler may not enforce left-to-right evaluation order in braced initializer list

The elements of a braced initializer list are to be evaluated in left-to-right order. There are two cases in which the compiler is unable to guarantee this order: the first is when some of the elements are objects passed by value; the second is when compiling with /clr and some of the elements are fields of objects or are array elements. When the compiler can't guarantee left-to-right evaluation it emits warning C4868.

This warning can be generated as a result of compiler conformance work that was done for Visual Studio 2015 Update 2. Code that compiled prior to Visual Studio 2015 Update 2 can now generate C4868.

This warning is off by default. Use /Wall to activate this warning.

To resolve this warning, first consider whether left-to-right evaluation of the initializer list elements is necessary, such as when evaluation of the elements might produce order-dependent side-effects. In many cases, the order in which elements are evaluated does not have an observable effect.

If the order of evaluation must be left-to-right, consider if it's possible to pass the elements by const reference instead. A change such as this eliminates the warning in the following code sample.

Example

This sample generates C4868, and shows a way to fix it:

// 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};
};