Compartir a través de


Advertencia del compilador (nivel 4) C4866

el compilador "file(line_number)" podría no exigir el orden de evaluación de izquierda a derecha para la llamada a operator_name

Comentarios

A partir de C++17, los operandos de los operadores ->*, [], >> y << se deben evaluar en orden de izquierda a derecha. Hay dos casos en los que el compilador no puede garantizar este orden:

  • cuando una de las expresiones del operando es un objeto que se pasa por valor o contiene un objeto que se pasa por valor, o

  • cuando se compila con /clr y uno de los operandos es un campo de un objeto o un elemento de una matriz.

El compilador emite una advertencia C4866 cuando no puede garantizar la evaluación de izquierda a derecha. Esta advertencia solo se genera si se especifica /std:c++17 o posterior, ya que el requisito de orden de izquierda a derecha de estos operadores se introdujo en C++17.

Esta advertencia está desactivada de manera predeterminada. Puede usar /Wall o /wN4866 para habilitarla en la línea de comandos como una advertencia de nivel N, o bien usar #pragma warning en el archivo de origen. Para más información, consulte Advertencias del compilador desactivadas de manera predeterminada.

Esta advertencia se introdujo en la versión 15.9 de Visual Studio 2017 como resultado del trabajo del compilador para cumplir con el estándar C++17. El código que se compilaba sin advertencias en versiones del compilador anteriores a la versión 15.9 de Visual Studio 2017 ahora puede generar la advertencia C4866. Si desea obtener información sobre cómo deshabilitar las advertencias introducidas en una versión determinada del compilador o una versión posterior, consulte Advertencias del compilador por versión del compilador.

Para resolver esta advertencia, primero considere si es necesaria la evaluación de izquierda a derecha de los elementos del operador, por ejemplo, cuando la evaluación de los operandos podría producir efectos secundarios dependientes del orden. En muchos casos, el orden en el que se evalúan los operandos no tiene un efecto observable.

Si el orden de evaluación debe ser de izquierda a derecha, considere si puede pasar los elementos por referencia const en su lugar. Este cambio elimina la advertencia en el siguiente ejemplo de código.

Ejemplo

Este ejemplo genera la advertencia C4866 y muestra una manera de corregirla:

// C4866.cpp
// compile with: /w14866 /std:c++17

class HasCopyConstructor
{
public:
    int x;

    HasCopyConstructor(int x) : x(x) {}
    HasCopyConstructor(const HasCopyConstructor& h) : x(h.x) { }
};

int operator->*(HasCopyConstructor a, HasCopyConstructor b) { return a.x + b.x; }

// This version of operator->* does not trigger the warning:
// int operator->*(const HasCopyConstructor& a, const HasCopyConstructor& b) { return a.x + b.x; }

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

    a->*b;        // C4866 for call to operator->*
};