Aviso do compilador (nível 4) C4868

O compilador 'file(line_number)' pode não impor a ordem de avaliação da esquerda para a direita na lista de inicializadores entre chaves

Os elementos de uma lista de inicializadores entre chaves devem ser avaliados na ordem da esquerda para a direita. Há dois casos em que o compilador não consegue garantir essa ordem: o primeiro é quando alguns dos elementos são objetos passados por valor; o segundo é ao compilar com /clr tendo alguns dos elementos como campos de objetos ou elementos de matriz. O compilador emite um aviso C4868 quando não é capaz de garantir a avaliação da esquerda para a direita.

Esse aviso pode ser gerado como resultado do trabalho de conformidade do compilador que foi feito para o Visual Studio 2015 Atualização 2. O código compilado antes do Visual Studio 2015 Atualização 2 agora gerará C4868.

Esse aviso está desativado por padrão. Use /Wall para ativar este aviso.

Para resolver esse aviso, considere primeiro se a avaliação da esquerda para a direita dos elementos da lista do inicializador é necessária; por exemplo, quando a avaliação dos elementos pode produzir efeitos colaterais dependentes da ordem. Em muitos casos, a ordem na qual os operandos são avaliados não tem efeitos observáveis.

Se a ordem da avaliação precisar ser da esquerda para a direita, considere se não é possível passar os elementos por referência const. Essa alteração elimina o aviso no exemplo de código a seguir.

Exemplo

Este exemplo gera C4868 e mostra uma maneira de corrigi-lo:

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