IT rekvalifikácia. Seniorní programátori zarábajú až 6 000 €/mesiac a rekvalifikácia je prvým krokom. Zisti, ako na to!

Diskusia – 4. diel - Makrá v programovacom jazyku C

Späť

Upozorňujeme, že diskusie pod našimi online kurzami sú nemoderované a primárne slúžia na získavanie spätnej väzby pre budúce vylepšenie kurzov. Pre študentov našich rekvalifikačných kurzov ponúkame možnosť priameho kontaktu s lektormi a študijným referentom pre osobné konzultácie a podporu v rámci ich štúdia. Toto je exkluzívna služba, ktorá zaisťuje kvalitnú a cielenú pomoc v prípade akýchkoľvek otázok alebo projektov.

Komentáre
Avatar
Luboš Běhounek Satik:28.7.2014 18:14

Bacha na SQR / SQRT :)

Jinak osobně se snažím makrům vyhýbat a používám je spíše opravdu pro rozlišení debug/release, x86/x64 a nebo třeba platformy (OS), pro kterou se kompiluje.

U kratších funkcí se dá místo makra použít inline funkce a žádná režie volání funkce pak není.

Nadužívání maker dokáže kód strašně znepřehlednit, když používate makro v makru v makru v makru, tak se v tom člověk lehce zamotá.

Editované 28.7.2014 18:15
Odpovedať
28.7.2014 18:14
https://www.facebook.com/peasantsandcastles/
Avatar
SPoon
Tvůrce
Avatar
Odpovedá na Luboš Běhounek Satik
SPoon:28.7.2014 18:55

Ahoj, díky za připomínky.

Klíčové slovo inline (C99) nebo const (C89) je převzato z jazyka C++. I když by měla být podpora těchto klíčových slov samozřejmostí, nemusí tomu tak ve všech C kompilátorech být.

Je ale pravda, že dnes se už doporučuje funkčním makrům vyhnout a místo makra pro definování hodnot je lepší použít klíčové slovo const. Přidám do článku ještě jednu podkapitolu. :)

Editované 28.7.2014 18:55
 
Odpovedať
28.7.2014 18:55
Avatar
Odpovedá na SPoon
Libor Šimo (libcosenior):29.7.2014 7:08

Veľmi dobrý článok.
Námet témy na ďalší článok navrhujem :
pointery a pointerová aritmetika;
štruktúry, uniony a výčtové typy;
bitové operácie.
A myslím, že by bolo dobré ku každému článku vymyslieť cvičenia, aby sme si to mohli vyskúšať prakticky.

Odpovedať
29.7.2014 7:08
Aj tisícmíľová cesta musí začať jednoduchým krokom.
Avatar
paja
Člen
Avatar
paja:30.7.2014 6:05

Moc pěkný článek. Pěkné shrnutí problematiky. Osobně se snažím makrům spíš vyhnout.Přimlouval bych za pokračování C čka.;)

 
Odpovedať
30.7.2014 6:05
Avatar
Bertram
Člen
Avatar
Bertram:10.8.2014 6:58

citace z článku:
Klíčové slovo const se může vyskytovat před definicí libovolné proměnné a znemožní jakkoli manipulovat s jejím obsahem. V případě, že se pokusíte hodnotu změnit, skončí proces kompilace chybou.

Takto definovaná konstanta je uložena na rozdíl od "symbolické" v paměti, takže jde její hodnota změnit pomocí ukazatele.

const int SIZE = 10;
int* p_SIZE = &SIZE;
*p_SIZE = 100;
printf("SIZE = %d\n", SIZE);
 
Odpovedať
10.8.2014 6:58
Avatar
SPoon
Tvůrce
Avatar
Odpovedá na Bertram
SPoon:10.8.2014 18:28

Ahoj,

díky za připomínku. Správně by to ale mělo být:

const int SIZE = 10;
int* p_SIZE = (int *)&SIZE;
*p_SIZE = 100;
printf("SIZE = %d\n", SIZE);

Pokud se reference nepřetypuje, měl by kompilátor zahlásit chybu.

 
Odpovedať
10.8.2014 18:28
Avatar
coells
Tvůrce
Avatar
Odpovedá na Bertram
coells:10.8.2014 20:10

Tohle je velice nebezpečný kód a není pravda, že konstanta musí být v paměti. Je několik variant, co se stane:

  1. program vypíše hodnotu 100
  2. program vypíše hodnotu 10
  3. program skončí na SEGFAULT

Konstantní hodnoty vůbec nemusí být alokované v paměti nebo dokonce v zapisovatelné paměti. Všechno záleží jenom na kompilátoru, typu zapnuté optimalizace a způsobu nalinkování knihovny.

 
Odpovedať
10.8.2014 20:10
Avatar
SPoon
Tvůrce
Avatar
Odpovedá na coells
SPoon:10.8.2014 22:05

Prováděli jsme testy na jednom typu kompilátoru a pokud byla konstantní proměnná menší jak 16-bitů, tak se chovala stejně jako konstanta zadefinovaná pomocí makra #define. To znamená, že nebyla uložena v paměti a kdekoli byla konstanta použita, byla přímo nahrazena číselnou hodnotou. Pokud byla konstanta větší, kompilátor pro ni vyhradil místo v paměti.

V tomto případě, ale souhlasím s coellsem, protože výše uvedený příklad zcela narušuje principy bezpečného programování.

 
Odpovedať
10.8.2014 22:05
Avatar
coells
Tvůrce
Avatar
Odpovedá na SPoon
coells:10.8.2014 22:28

Používám LLVM 5.1 a povedlo se mi snadno nasimulovat všechny tři situace, které jsem zmínil. Hodně vtipná je varianta 1+2, kdy mi kód vypíše současně 100 i 10.

To, co uvádíš, je dost podivné chování a moc mi nedává smysl. Spíš bych řekl, že tam byly jiné faktory, které jste přehlídli.

 
Odpovedať
10.8.2014 22:28
Avatar
SPoon
Tvůrce
Avatar
Odpovedá na coells
SPoon:11.8.2014 9:21

V případě, že je k dispozici malé množství paměti RAM (například 128 KB), což je typické pro embedded systémy, tak je velmi důležité, aby konstanty zbytečně nezabíraly potřebné místo. V takovém případě provede kompilátor optimalizaci - konstanta se do paměti neumístí a každý její výskyt přímo nahradí danou hodnotou.

Daná hodnota musí ale splnit dvě základní pravidla. Prvním je, že se na danou konstantu nikdy neodkážeme pomocí pointeru. Druhým pravidlem je, že číselná hodnota musí být velká tak, aby se vešla do jedné instrukce (to pro 16-bitovou instrukční sadu a 32-bitovou architekturu znamená, že číslo musí být velké maximálně 16-bitů).

Samozřejmě výše uvedené vlastnosti jsou "compiler specific", tedy závislé na typu použitého kompilátoru.

PS: Podle mého názoru se musí kompilátor pokaždé chovat deterministicky. Pokud tedy zareaguje ve stejné situaci pokaždé jinak (jako např. v tvém případě), není to správné chování.

Editované 11.8.2014 9:22
 
Odpovedať
11.8.2014 9:21
Robíme čo je v našich silách, aby bola tunajšia diskusia čo najkvalitnejšia. Preto do nej tiež môžu prispievať len registrovaní členovia. Pre zapojenie sa do diskusie sa zaloguj. Ak ešte nemáš účet, zaregistruj sa, je to zadarmo.

Zatiaľ nikto nevložil komentár - buď prvý!