Braki w teorii i wiedzy „jak kompilator działa pod spodem” mogą być bardziej bolesne, niż się wydaje. Prosta na pierwszy rzut oka rzecz: kolejność ewaluacji argumentów w funkcji. Podajemy od lewej do prawej, ale w jakiej kolejności czyta komputer? Tak jak napiszemy? Czy może odwrotnie, od prawej do lewej? Dokumentacja C++ daje klarowną odpowiedź: nie wiadomo!

5.2.2 Function call


8 The order of evaluation of arguments is unspecified. All side effects of argument expression evaluations take effect before the function is entered. The order of evaluation of the postfix expression and the argument expression list is unspecified.

Niby nie wiadomo, ale jednak trochę wiadomo, bo chyba wszystkie implementacje C/C++, oprócz CLanga, stosują kolejność od prawej do lewej. Czyli całkiem nieintuicyjną dla kogoś, kto nie wie, jak działa stos. Jak to się przekłada na praktykę?

Powiedzmy, że mamy w pliku tekstowym wypisane pozycje i wymiary kilku prostokątów:

rect_x rect_y rect_width rect_height
200 200 50 50

Teraz, ładujemy dane z pliku do struktury i przy okazji żydzimy na utworzeniu kilku zmiennych pomocniczych:

No i już: mamy buga i spędzamy następne trzy godziny na zastanawianiu się, czemu dane są zamienione miejscami. Kompilator odczyta instrukcje od końca, tak, że ostatnie getToken() wykona się jako pierwsze i przypisze współrzędną X do wysokości prostokąta.  Poprawny kod będzie wyglądał jakoś tak:

Sytuacja z życia wzięta, sprzed trzech lat podczas pisania edytora map do prostej gry. Od tego czasu przykładam się trochę bardziej do teorii i codziennie zanim zasnę, czytam po kilka stron dokumentacji C++ przed ołtarzykiem Bjarna Stroustrupa. Polecam!

  • Did you like it?
  • Yes   No