Jeśli mamy trzy funkcje (foo, bar i baz), które są tak złożone ...
foo(bar(), baz())
Czy standard C ++ gwarantuje, że pasek zostanie oceniony przed baz?
Nie, nie ma takiej gwarancji. Nie jest określony zgodnie ze standardem C ++.
Bjarne Stroustrup również mówi to wyraźnie w "Języku programowania C ++", 3. wydanie, sekcja 6.2.2, z pewnym uzasadnieniem:
Lepszy kod można wygenerować bez ograniczeń dotyczących kolejności oceny wyrażeń
Chociaż technicznie odnosi się to do wcześniejszej części tej samej sekcji, która mówi, że kolejność oceny części wyrażenia jest również nieokreślona, tj.
int x = f(2) + g(3); // unspecified whether f() or g() is called first
Z [5.2.2] wywołania funkcji,
Dlatego nie ma gwarancji, że
bar()
będzie działać wcześniejbaz()
, tylko tobar()
ibaz()
zostanie wywołane wcześniejfoo
.Zwróć również uwagę na [5] Wyrażenia, że:
więc nawet jeśli zostały pytaniem, czy
bar()
potrwa zanimbaz()
sięfoo(bar() + baz())
kolejność jest nadal nieokreślone.źródło
&
,&&
gwarantuje ocenę od lewej do prawej: drugi argument nie jest oceniany, jeśli pierwszy operand jestfalse
."Nie ma określonej kolejności dla bar () i baz () - jedyną rzeczą, o której mówi Standard, jest to, że oba zostaną ocenione przed wywołaniem foo (). Ze standardu C ++, sekcja 5.2.2 / 8:
źródło
bar
, następnie linii 1baz
, następnie linii 2bar
itd.), Co również jest miłe. :-)C ++ 17 określa kolejność oceny dla operatorów, która była nieokreślona do C ++ 17. Zobacz pytanie Jakie są gwarancje kolejności oceny wprowadzone przez C ++ 17? Ale zwróć uwagę na swój wyraz twarzy
ma jeszcze nieokreśloną kolejność oceny.
źródło
W C ++ 11 odpowiedni tekst można znaleźć w 8.3.6 Default arguments / 9 (moje podkreślenie)
Ta sama słówka jest używana również w standardzie C ++ 14 i znajduje się w tej samej sekcji .
źródło
Jak inni już zauważyli, standard nie podaje żadnych wskazówek co do kolejności oceny dla tego konkretnego scenariusza. Ta kolejność oceny jest następnie pozostawiana kompilatorowi, a kompilator może mieć gwarancję.
Należy pamiętać, że standard C ++ jest tak naprawdę językiem, który instruuje kompilator, jak konstruować asembler / kod maszynowy. Norma to tylko jedna część równania. Tam, gdzie standard jest niejednoznaczny lub ma konkretnie zdefiniowaną implementację, należy zwrócić się do kompilatora i zrozumieć, w jaki sposób tłumaczy on instrukcje C ++ na prawdziwy język maszynowy.
Tak więc, jeśli kolejność oceny jest wymaganiem lub przynajmniej ważna, a zgodność z różnymi kompilatorami nie jest wymaganiem, zbadaj, w jaki sposób Twój kompilator ostatecznie połączy to w całość, Twoja odpowiedź może ostatecznie leżeć w tym miejscu. Zauważ, że kompilator może zmienić swoją metodologię w przyszłości
źródło