Ostrzeżenie kompilatora (poziom 4) C4868
Kompilator "file(line_number)" może nie wymuszać kolejności oceny od lewej do prawej na liście inicjatorów nawiasów klamrowych
Elementy listy inicjatora nawiasów klamrowych mają być oceniane w kolejności od lewej do prawej. Istnieją dwa przypadki, w których kompilator nie może zagwarantować tej kolejności: pierwszy to, gdy niektóre elementy są obiektami przekazywanymi przez wartość; drugi jest podczas kompilowania z elementami /clr
, a niektóre elementy są polami obiektów lub elementami tablicy. Gdy kompilator nie może zagwarantować oceny od lewej do prawej, emituje ostrzeżenie C4868.
To ostrzeżenie można wygenerować w wyniku pracy kompilatora zgodności wykonanej dla programu Visual Studio 2015 Update 2. Kod skompilowany przed programem Visual Studio 2015 Update 2 może teraz wygenerować C4868.
To ostrzeżenie jest domyślnie wyłączone. Użyj polecenia /Wall
, aby aktywować to ostrzeżenie.
Aby rozwiązać to ostrzeżenie, najpierw należy rozważyć, czy konieczna jest ocena elementów listy inicjatora od lewej do prawej, na przykład w przypadku oceny elementów, które mogą powodować skutki uboczne zależne od kolejności. W wielu przypadkach kolejność oceniania elementów nie ma zauważalnego efektu.
Jeśli kolejność oceny musi być od lewej do prawej, rozważ, czy zamiast tego można przekazać elementy według const
odwołania. Taka zmiana eliminuje ostrzeżenie w poniższym przykładzie kodu.
Przykład
Ten przykład generuje kod C4868 i pokazuje sposób jego naprawy:
// C4868.cpp
// compile with: /c /Wall
#include <cstdio>
class HasCopyConstructor
{
public:
int x;
HasCopyConstructor(int x): x(x) {}
HasCopyConstructor(const HasCopyConstructor& h): x(h.x)
{
printf("Constructing %d\n", h.x);
}
};
class TripWarning4868
{
public:
// note that taking "HasCopyConstructor" parameters by-value will trigger copy-construction.
TripWarning4868(HasCopyConstructor a, HasCopyConstructor b) {}
// This variation will not trigger the warning:
// TripWarning4868(const HasCopyConstructor& a, const HasCopyConstructor& b) {}
};
int main()
{
HasCopyConstructor a{1};
HasCopyConstructor b{2};
// the warning will indicate the below line, the usage of the braced initializer list.
TripWarning4868 warningOnThisLine{a, b};
};