Partager via


Avertissement du compilateur (niveau 4) C4866

Le compilateur 'file(line_number)' peut ne pas appliquer l’ordre d’évaluation de gauche à droite pour l’appel à operator_name

Notes

À compter de C++17, les opérandes des opérateurs ->*, [], >>et << doivent être évalués dans l’ordre de gauche à droite. Il existe deux cas dans lesquels le compilateur est incapable de garantir cet ordre :

  • lorsqu’une des expressions de l’opérande est un objet passé par une valeur ou contient un objet passé par une valeur, ou

  • lors de la compilation à l’aide de /clr, et l’une des opérandes est un champ d’un objet ou un élément de tableau.

Le compilateur émet l’avertissement C4866 quand il ne peut pas garantir l’évaluation de gauche à droite. Cet avertissement est généré uniquement si /std:c++17 ou une version ultérieure est spécifié, car l’exigence de l’ordre de gauche à droite de ces opérateurs a été introduite en C++17.

Cet avertissement est désactivé par défaut ; vous pouvez utiliser /Wall ou /wN4866 pour l’activer sur la ligne de commande en tant qu’avertissement N de niveau , ou utiliser #pragma avertissement dans votre fichier source. Pour plus d’informations, consultez les avertissements du compilateur désactivés par défaut.

Cet avertissement a été introduit dans Visual Studio 2017 version 15.9 en raison du travail de conformité du compilateur pour la norme C++17. Le code compilé sans avertissements dans les versions du compilateur avant Visual Studio 2017 version 15.9 peut désormais générer C4866. Pour plus d’informations sur la désactivation des avertissements introduits dans une version particulière du compilateur ou une version ultérieure, consultez Avertissements du compilateur par version du compilateur.

Pour résoudre cet avertissement, commencez par déterminer si l’évaluation de gauche à droite des éléments d’opérateur est nécessaire, par exemple lorsque l’évaluation des éléments peut produire des effets secondaires dépendants de l’ordre. Dans de nombreux cas, l’ordre dans lequel les éléments sont évalués n’a pas d’effet observable.

Si l’ordre d’évaluation doit être de gauche à droite, déterminez si vous pouvez passer les éléments par const référence à la place. Cette modification supprime l’avertissement dans l’exemple de code suivant.

Exemple

Cet exemple génère l’erreur C4866 et montre un moyen de le corriger :

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