Dela via


Kompilatorvarning (nivå 4) C4866

Kompilatorn "file(line_number)" kanske inte framtvingar utvärderingsordning från vänster till höger för anrop till operator_name

Anmärkningar

Från och med C++17 måste operanderna för operatorerna ->*, [], >>och << utvärderas i vänster-till-höger-ordning. Det finns två fall där kompilatorn inte kan garantera den här ordningen:

  • när ett av operanduttrycken är ett objekt som skickas av ett värde eller innehåller ett objekt som skickas av ett värde, eller

  • när den kompileras med hjälp av /clr, och en av operanderna är ett fält i ett objekt eller ett matriselement.

Kompilatorn genererar varning C4866 när den inte kan garantera utvärdering från vänster till höger. Den här varningen genereras endast om /std:c++17 eller senare anges, eftersom kravet på ordning från vänster till höger för dessa operatorer infördes i C++17.

Den här varningen är inaktiverad som standard. du kan använda /Wall eller /wN4866 för att aktivera den på kommandoraden som en nivå N-varning eller använda #pragma varning i källfilen. Mer information finns i Kompilatorvarningar som är inaktiverade som standard.

Den här varningen introducerades i Visual Studio 2017 version 15.9 som ett resultat av kompilatorns efterlevnadsarbete för C++17-standarden. Kod som kompilerats utan varningar i versioner av kompilatorn före Visual Studio 2017 version 15.9 kan nu generera C4866. Information om hur du inaktiverar varningar som introduceras i en viss kompilatorversion eller senare finns i Kompilatorvarningar efter kompilatorversion.

För att lösa den här varningen bör du först överväga om vänster-till-höger-utvärdering av operatorelementen är nödvändig, till exempel när utvärdering av elementen kan ge ordningsberoende biverkningar. I många fall har den ordning i vilken element utvärderas inte någon observerbar effekt.

Om utvärderingsordningen måste vara från vänster till höger bör du överväga om du kan skicka elementen med const referens i stället. Den här ändringen eliminerar varningen i följande kodexempel.

Example

Det här exemplet genererar C4866 och visar ett sätt att åtgärda det:

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