(++i)*(++i)

Martin Mares mj na atrey.karlin.mff.cuni.cz
Pondělí Únor 1 12:01:12 CET 1999


Zdravim,

> Podle mne je zásadní chyba v optimalizaci.
> Pravdipodobni nikde mezi lexikálním a syntaktickým analyzátorem dojde ke
> spojení kódu a (++i)*(++i) je nahrazeno LEX1*LEX2, porovnány LEX1 a LEX2 a
> provedeno #define LEX3=LEX2 a celý výraz nahrazen LEX3*LEX3.
> Do tabulky je ulo3/4en LEX3 a poi poedpoeítání výsledku dojde k tomu, 3/4e je
> vygenerováno mov LEX3,ADDR(i); inc(LEX3); inc(LEX3); result=LEX3^2;
> Tady bych vidil chybu kompilatoru, nikoli programátora.

   Ja tedy nikoliv. Standard jazyka C jednoznacne odlisuje poradi vyhodnocovani
vyrazu a poradi vykonavani side-effectu (to jsou napriklad zminovane incrementy).
Zavorky ovlivnuji pouze vyhodnocovani a na side-effecty nemaji zadneho ucinku,
zatimco sequencing-pointy (&&, ||, volani funkce, navrat z funkce, ;, ?, :,
carka jakozto operator zapomenuti) ovlivnuji poradi vykonavani side-effectu.
Jedina vazba mezi vyhodnocovanim a side-effecty, ktera je normou zarucena,
je, ze preinkrement/predekrement se provede pred vyhodnocenim a postinc/postdec
po vyhodnoceni. Je-li ovsem ve vyrazu mezi dvema sequencing-pointy vice
side-effectu, pak nikdo nezarucuje, v jakem budou vykonany poradi a kazdy
program, ktery na libovolne konkretni poradi spoleha, je z definice chybny.
 
				Have a nice fortnight
-- 
Martin `MJ' Mares   <mj na ucw.cz>   http://atrey.karlin.mff.cuni.cz/~mj/
Faculty of Math and Physics, Charles University, Prague, Czech Rep., Earth
"Do not believe in miracles -- rely on them."


Další informace o konferenci Linux