Rozważmy pętli while w ANSI C, którego jedynym celem jest, aby opóźnić wykonanie:Czy kompilator ANSI C może usunąć pętlę opóźnienia?
unsigned long counter = DELAY_COUNT;
while(counter--);
Widziałem to kiedyś wiele do egzekwowania opóźnień w systemach wbudowanych, gdzie np. nie ma funkcji i timery lub przerwań są ograniczone.
Mój odczyt standardu ANSI C polega na tym, że może on zostać całkowicie usunięty przez zgodny kompilator. To ma żadnych skutków ubocznych opisanych w 5.1.2.3:
dostępu do lotnego obiekt, modyfikowania obiektu, modyfikując plik lub wywołanie funkcji, które ma każdy z tych operacji są wszystkie skutki uboczne, które są zmiany w stanie środowiska wykonawczego.
... i ta sekcja mówi:
rzeczywistej implementacji nie musi oceniać część wyrazu, jeżeli można wywnioskować, że jego wartość nie jest używany i że bez bólu, skutki uboczne są produkowane (w tym wszelkie spowodowane przez wywołanie funkcji lub uzyskanie dostępu do obiektu zmiennego).
Czy to oznacza, że pętlę można zoptymalizować? Nawet jeśli counter
było volatile
?
Uwagi:
- że to nie jest to samo, co Are compilers allowed to eliminate infinite loops?, ponieważ odnosi się do nieskończonych pętli i pojawiają się pytania o to, kiedy program może rozwiązać w ogóle. W takim przypadku program z pewnością przekroczy punkt w jakimś momencie, optymalizacji lub nie.
- Wiem, co robi GCC (usuwa pętlę dla
-O1
lub wyższej, chyba żecounter
jestvolatile
), ale chcę wiedzieć, co dyktuje standard.
Dopóki zachowanie * obserable * nie zostanie zmienione, standard C nie zabroniłby optymalizacji tej pętli. Tak więc standard nie dyktuje niczego konkretnego. –