Freigeben über


Compilerwarnung (Stufe 4) C4866

Der Compiler "file(line_number)" erzwingt möglicherweise nicht die Reihenfolge der Links-nach-rechts-Auswertung für den Aufruf von operator_name

Hinweise

Ab C++17 müssen die Operanden der Operatoren ->*, [], >>und << in der Reihenfolge von links nach rechts ausgewertet werden. Es gibt zwei Fälle, in denen der Compiler diese Reihenfolge nicht sicherstellen kann:

  • wenn es sich bei einem der Operandenausdrücke um ein nach Wert übergebenes Objekt handelt oder er ein nach Wert übergebenes Objekt enthält oder

  • wenn er mithilfe von /clr kompiliert wird und einer der Operanden ein Feld eines Objekts oder ein Arrayelement ist.

Der Compiler gibt die Warnung C4866 aus, wenn er die Auswertung von links nach rechts nicht sicherstellen kann. Diese Warnung wird nur generiert, wenn /std:c++17 oder höher angegeben wird, da die Anforderung der Links-nach-rechts-Reihenfolge dieser Operatoren in C++17 eingeführt wurde.

Diese Warnung ist standardmäßig deaktiviert; Sie können /Wall oder /wN4866 verwenden, um sie in der Befehlszeile als Warnung der Ebene N zu aktivieren, oder #pragma Warnung in Der Quelldatei verwenden. Weitere Informationen finden Sie unter Compilerwarnungen, die standardmäßig deaktiviert sind.

Diese Warnung wurde in Visual Studio 2017, Version 15.9, als Ergebnis der Compilerkonformität für den C++17-Standard eingeführt. Code, der ohne Warnungen in Versionen des Compilers vor Visual Studio 2017, Version 15.9 kompiliert wurde, kann jetzt C4866 generieren. Informationen zum Deaktivieren von Warnungen, die in einer bestimmten Compilerversion oder höher eingeführt wurden, finden Sie unter Compilerwarnungen nach Compilerversion.

Um diese Warnung zu beheben, überlegen Sie zuerst, ob die Links-nach-rechts-Bewertung der Operatorelemente erforderlich ist, z. B. wenn die Auswertung der Elemente zu orderabhängigen Nebenwirkungen führen kann. In vielen Fällen hat die Reihenfolge, in der Elemente ausgewertet werden, keine feststellbare Wirkung.

Wenn die Reihenfolge der Auswertung von links nach rechts erfolgen muss, überlegen Sie, ob Sie die Elemente stattdessen per const Verweis übergeben können. Diese Änderung entfernt die Warnung im folgenden Codebeispiel.

Beispiel

In diesem Beispiel wird C4866 generiert, und es wird eine Möglichkeit zum Beheben gezeigt:

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