Share via


Avviso del compilatore (livello 4) C4866

Il compilatore 'file(line_number)' potrebbe non applicare l'ordine di valutazione da sinistra a destra per la chiamata a operator_name

Osservazioni:

A partire da C++17, gli operandi degli operatori ->*, [], >>e << devono essere valutati in ordine da sinistra a destra. Esistono due casi in cui il compilatore non è in grado di garantire questo ordine:

  • quando una delle espressioni dell'operando è un oggetto passato per valore o contiene un oggetto passato per valore, oppure

  • quando la compilazione viene eseguita con /clr e uno degli operandi è un campo di un oggetto o un elemento di matrice.

Il compilatore genera l'avviso C4866 quando non è possibile garantire la valutazione da sinistra a destra. Questo avviso viene generato solo se /std:c++17 o versioni successive viene specificato, perché il requisito dell'ordine da sinistra a destra di questi operatori è stato introdotto in C++17.

Questo avviso è disattivato per impostazione predefinita; è possibile usare /Wall o /wN4866 per abilitarlo nella riga di comando come avviso di livello N oppure usare #pragma avviso nel file di origine. Per altre informazioni, vedere Avvisi del compilatore disattivati per impostazione predefinita.

Questo avviso è stato introdotto in Visual Studio 2017 versione 15.9 in seguito al funzionamento della conformità del compilatore per lo standard C++17. Il codice compilato senza avvisi nelle versioni del compilatore prima di Visual Studio 2017 versione 15.9 può ora generare C4866. Per informazioni su come disabilitare gli avvisi introdotti in una determinata versione del compilatore o versioni successive, vedere Avvisi del compilatore per versione del compilatore.

Per risolvere questo avviso, valutare innanzitutto se è necessaria la valutazione da sinistra a destra degli elementi dell'operatore, ad esempio quando la valutazione degli elementi potrebbe produrre effetti collaterali dipendenti dall'ordine. In molti casi, l'ordine in cui gli elementi vengono valutati non ha un effetto osservabile.

Se l'ordine di valutazione deve essere da sinistra a destra, valutare se è possibile passare gli elementi in const base al riferimento. Questa modifica consente di eliminare l'avviso nell'esempio di codice seguente.

Esempio

Questo esempio genera l'errore C4866 e mostra un modo per correggerlo:

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