Hogyan tudnád megmondani a C fordítónak, hogy ezt a kódrészletet NE optimalizálja ki?
Van az alábbi kódrészletem:
Nem értettem, hogy miért mindig 0-val tér vissza. Aztán észrevettem, hogyha valami olyasmit írok be a ciklusba, ami mindenképpen csinál valamit - pl. putchar()-al kiírok egy karaktert -, akkor már megkapom a helyes eredményt.
Tehát valószínűsítem, az a gond, hogy a fordító úgy optimalizálja ki ezt a kódot, hogy szerinte egyszer sem futna le a ciklus.
Milyen kulcsszóval, vagy hogyan tudom elérni, hogy az optimalizáció ne "nulláza ki" ezt a kódot tévesen?
változókra volatile kulcsszó szokott segíteni, de az nem (csak) a fordítónak szól. Ha gcc-vel fordítod, akkor a -O0 flaggel tudod beadni hogy ne optimalizáljon semmit.
De egész pontosan mi ez, amit számolgatsz a függvényben? Egy árva mukkot nem lehet belőle érteni.
A, b, x nevű változók, semmi komment...
A függvénynév and az bitműveletre utalna, de akkor miért előjeles számok vannak, és miért előjel nélküli tér vissza?
Ez az egész így elég ronda...
X idétlen posztinkremens használata helyett sokkal átláthatóbb lenne egy for ciklus használata például. Az átláthatóságot rontja és hibához vezethet, hogy az x előbb van kiértékelve, és utána csökkenti az eredményt például...
Két lehetőség van.
Az egyik, hogy külön fájlban írod meg azt, amit nem akarsz optimalizálni, majd a fájl objectjét hozzá szerkeszted a többihez.
A másik, hogy assembly kimenetet generáltatsz a fordítóval és abban helyre teszed a dolgokat.
A volatile nem erre való, hanem olyan változókhoz, amelyek kívülről, a programtól függetlenül kapnak értéket. Pl. egy portról olvasnak be.
Én azért kérdeztem, hogy milyen fordítót használ, mert azért vannak erre lehetőségek. GCC-nél például létezik ilyen:
#pragma GCC optimize (string, …)
This pragma allows you to set global optimization options for functions defined later in the source file.[...]
#pragma GCC push_options
#pragma GCC pop_options
These pragmas maintain a stack of the current target and optimization options. It is intended for include files where you temporarily want to switch to using a different ‘#pragma GCC target’ or ‘#pragma GCC optimize’ and then to pop back to the previous options.
És lehet ilyen attribútumot definiálni:
int foo(int i) __attribute__((optimize("-O3")));
"The optimize attribute is used to specify that a function is to be compiled with different optimization options than specified on the command line. The optimize attribute arguments of a function behave as if appended to the command-line.[...]"
A volatile is jó lehet, mert ahogy írja #3-as, a "volatile nem erre való, hanem olyan változókhoz, amelyek kívülről, a programtól függetlenül kapnak értéket". Az ilyen változókat a fordító nem optimalizálja ki, bár ettől még másféle optimalizáció végbe mehet.
A kódban sok minden feleslegesnek tűnik. pl az a+=a és a b+=b nem jó semmire alapvetően, mert csak azt nézed, hoyg 0-nál kisebbek-e, vagy sem. Akkor lesz valami eredmény ennek, amikor túlcsordulnak. Ha nem elég nagyok ahhoz, hogy túlcsorduljanak, akkor egyedül abban az esetben kell 0-tól különböző eredménynek lennie, ha a is és b is kisebb, mint 0, de ekkor is csak egy érték lesz visszaadva, mivel c értéke mindig csak a saját értékétől függ, és akkor is folyamatosan változtatva lesz. Ha van túlcsordulás, akkor pedig attól függően, hogy milyen hamar lesz, sokféle eredmény lehet.
Nekem ez a kód:
#include <stdio.h>
unsigned long and(signed long a, signed long b) {
unsigned long c;
unsigned char x;
c = 0;
x = 32;
while (x--) {
c += c;
c += a < 0 ? b < 0 : 0;
a += a;
b += b;
}
return c;
}
int main() {
printf("%ld\n", and(2, 3));
printf("%ld\n", and(-2, 3));
printf("%ld\n", and(2, -3));
printf("%ld\n", and(-2, -100));
printf("%ld\n", and(0, 0));
}
Ezt az eredményt adja, különböző optimalizációk mellett:
0
0
0
4294967295
0
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!