Поделиться через


Предупреждение компилятора (уровень 4) C4868

Компилятор file(line_number)" может не применять порядок оценки слева направо в списке инициализатора с скобками

Элементы списка инициализатора с скобками должны оцениваться в левом порядке в правом порядке. Существует два случая, когда компилятор не может гарантировать этот порядок: первое — когда некоторые элементы являются объектами, передаваемыми по значению; Во-вторых, при компиляции с /clr некоторыми элементами являются поля объектов или являются элементами массива. Если компилятор не может гарантировать слева направо, он выдает предупреждение C4868.

Это предупреждение можно создать в результате работы по соответствию компилятора, которая была выполнена для Visual Studio 2015 с обновлением 2. Код, скомпилированный до Visual Studio 2015 с обновлением 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};
};