C/Przenośność programów: Różnice pomiędzy wersjami

Usunięta treść Dodana treść
Mina86 (dyskusja | edycje)
m →‎Kompilacja warunkowa: zgubiłem spacje w kodzie
Mina86 (dyskusja | edycje)
Linia 12:
Zachowania niezdefiniowane są o wiele groźniejsze, gdyż zaistnienie takowego może spowodować dowolny efekt, który nie musi być nigdzie udokumentowany. Przykładem może tutaj być próba odwołania się do wartości wskazywanej przez wskaźnik o wartości NULL.
 
Jeżeli gdzieś w naszym programie zaistnieje sytuacja niezdefiniowanego zachowania, to nie jest już to kwestia przenośności kodu, ale po prostu błędu w kodzie, chyba że świadomie korzystamy z rozszerzenia naszego procesorakompilatora. Rozważmy odwoływanie się do wartości wskazywanej przez wskaźnik o wartości NULL. Ponieważ według standardu operacja taka ma niezdefiniowany skutek to w szczególności może spowodowaćwywołać jakiejśjakąś z góry określonejokreśloną funkcjifunkcję - kompilator może coś takiego zrealizować sprawdzając wartość wskaźnika przed każdą dereferencją, w ten sposób niezdefiniowane zachowanie dla konkretnego kompilatora stanie się jak najbardziej zdefiniowane.
 
Sytuacją wziętą z życia są operatory przesunięć bitowych, gdy działają na liczbach ze znakiem. Konkretnie przesuwanie w lewo liczb jest takdla wielu naprawdęprzypadków niezdefiniowane. Bardzo często jednak, w dokumentacji kompilatora działanie przesunięć bitowych dla liczb ze znakiem jest dokładnie opisanychopisane. Jest to o tyle interesujący fakt, iż wielu programistów nie zdaje sobie z niego sprawy i nieświadomie korzysta z rozszerzeń kompilatora.
 
Istnieje jeszcze trzecia klasa zachowań. Zachowania nieokreślone (ang. ''unspecified behaviour''). Są to sytuacje, gdy standard określa kilka możliwych sposobów w jaki dane wyrażenie może działać i pozostawia kompilatorowi decyzję co z tym dalej zrobić. Coś takiego nie musi być nigdzie opisane w dokumentacji i znowu poleganie na konkretnym zachowaniu jest błędem. Klasycznym przykładem może być kolejność obliczania argumentów wywołania funkcji.