Upozornění kompilátoru (úroveň 4) C4866
Kompilátor 'file(line_number)' nemusí vynutit pořadí vyhodnocení zleva doprava pro volání operator_name
Poznámky
Počínaje jazykem C++17 musí být operandy operátorů ->*, [] >>a << musí být vyhodnoceny v pořadí zleva doprava. Existují dva případy, kdy kompilátor nemůže zaručit toto pořadí:
pokud jeden z výrazů operandu je objekt předaný hodnotou nebo obsahuje objekt předaný hodnotou, nebo
při kompilaci pomocí /clr a jeden z operandů je pole objektu nebo prvku pole.
Kompilátor vygeneruje upozornění C4866, pokud nemůže zaručit vyhodnocení zleva doprava. Toto upozornění se vygeneruje pouze v případě, že /std:c++17
je zadáno nebo novější, protože požadavek na pořadí zleva doprava byl zaveden v jazyce C++17.
Toto upozornění je ve výchozím nastavení vypnuté; Můžete použít /Wall nebo /wN4866 k povolení na příkazovém řádku jako upozornění na úroveň N nebo použít #pragma upozornění ve zdrojovém souboru. Další informace najdete v tématu Upozornění kompilátoru, která jsou ve výchozím nastavení vypnutá.
Toto upozornění bylo zavedeno v sadě Visual Studio 2017 verze 15.9 v důsledku shody kompilátoru pro standard C++17. Kód kompilovaný bez upozornění ve verzích kompilátoru před sadou Visual Studio 2017 verze 15.9 teď může generovat C4866. Informace o tom, jak zakázat upozornění zavedená v konkrétní verzi kompilátoru nebo novější, naleznete v tématu Upozornění kompilátoru podle verze kompilátoru.
Chcete-li toto upozornění vyřešit, nejprve zvažte, zda je nezbytné vyhodnocení prvků operátoru zleva doprava, například při vyhodnocení prvků může vést k nežádoucím účinkům závislým na pořadí. V mnoha případech pořadí, ve kterém jsou prvky vyhodnoceny, nemá pozorovatelný účinek.
Pokud musí být pořadí vyhodnocení zleva doprava, zvažte, jestli místo toho můžete předat prvky odkazem const
. Tato změna eliminuje upozornění v následující ukázce kódu.
Příklad
Tato ukázka vygeneruje C4866 a ukazuje způsob, jak ji opravit:
// 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->*
};