1
Vývoj / Re:Rozdíl mezi ASM a strojovým kódem
« kdy: 18. 03. 2026, 11:06:06 »Váš kousek kódu může mít nedefinované chování kvůli aliasingu.A to prosím kde/jak?
Tato sekce Vám umožňuje zobrazit všechny příspěvky tohoto uživatele. Prosím uvědomte si, že můžete vidět příspěvky pouze z oblastí Vám přístupných.
Váš kousek kódu může mít nedefinované chování kvůli aliasingu.A to prosím kde/jak?
Tu podmíněnou kompilaci ale nedělá jazyk C ale C preprocesor.Tak jakto že The C Programming Language od Kernighana a Ritchieho z roku 1978 zmiňuje preprocesor?
Je to separátní tool, který ani nerozumí kompletní syntaxi C a používá se i pro jiné jazyky. Integrace preprocesoru do překladače proběhla až relativně nedávno, protože to oddělení mělo nepříjemné důsledky na použitelnost.
Abych dostal to makro ENDIANESS tak musím mít někde mrtě platformně závislé logiky.To je prosím celá mrtě logika, která je potřeba pro detekci endianity buildtoolem - ten checkne návratový kód.
#include <stdint.h>
int main(void)
{
uint32_t x = 1;
uint8_t *p = (uint8_t *)&x;
return p[0] == 1;
}
Ano na nějakých exotických systémech to asi i tak selže, ale umí toto nějaký jazyk lépe? V praxi na jakémkoliv moderním systému to bude fungovat.Btw, drtivá většina C kódu není přenositelná, ale je psaná v nějakém platformně závislém dialektu. Je to proto, že v přenositelné podmnožině C chybí naprosto zásadní věci. Např linux není psaný v C ale v GCC dialektu a při portování do clangu se do něj ten GCC dialekt přidal.Linux je nejpřenositelnější OS jaký existuje
No a nemyslím si že používají GCC kvůli tomu že by C nebylo přenositelné. Inline assembler je spíše praktická věc pro OS kód. Různé builtin funkce jsou spíše optimalizační techniky. Makro typeof zase umožňuje generičtější kód, což jenom šetří psaní... dalo by se bez toho všeho obejít. Které věci z GCC dialektu jsou striktně kvůli přenositelnosti bez kterých by se nedalo obejít?
Na to stačí jednoduchý #ifdefK ostatnímu se nebudu vracet, ale ten jednoduchý ifdef třeba na endiany bych chtěl vidět. Normálně potkávám několik obrazovek ifdefů, protože každý překladač, platforma a občas i verze mají ty makra nějak jinak.
případně runtime detekce se dá udělat taky, jak pro endianitu, tak pro dvojkový doplněk.

Pokud použiju separátní tool (který ani nezná kompletní syntaxi C) abych jím lepil platformně závislé kousky textu dohromady, můžu ještě mluvit o přenositelném jazyce?V C lze psát jak přenositelně, tak nepřenostitelně. Které věci jsou přenositelné, a které ne, je nutné znát.
A věci jako endiany nebo jestli mám vůbec dvojkový doplněk se zjišťují hůř.Na to stačí jednoduchý #ifdef
Tak zrovna u charu je to "implementation defined". Takže jazyk C definuje jen to, že to kompilátor "overridnout" prostě musí.u charu ano. U unsigned charu a signed charu nikoliv, ty jsou jasně definované. Jazyk je nabízí... takže co, zase tu budu řešit že někdo chtěl unsigned char a to unsigned tam nenapsal (a naopak)? Tady žádný problém v přenositelnosti z pohledu jazyka není.
Ano, v C se dá psát přenositelný kód. Ale protože je to jazyk z punkových časů, tak toho ta přenositelná podmnožina až tak moc neumí. A málo šedivé programátory to může překvapit, protože spousta těch věcí z dnešního pohledu už fakt nedává smysl.Super, takže se shodneme - C je přenositelný jazyk. Tímto můžeme debatu uzavřít.
To jsou zase plkyTeprve jazyk C vyřešil přenositelnost.V rámci možností. Pokud člověk například nepotřebuje vědět, jestli char je signed nebo unsigned. Nebo jak velký je int. Viz nedávné flame vlákno o bit shiftování signed intu.

Je vidět, že ses tu algoritmizaci neučil déle než těch tvých deset minut.Kód: [Vybrat]pokud voda bubla ... nalej ji do hrnku
pokud ne, bez o krok zpet
Pokud bys jí totiž pochopil, použil bys tvarKód: [Vybrat]dokud voda nevře
# Get all interface names once
interfaces=$(ip link show | grep -E '^[0-9]+:' | cut -d: -f2 | tr -d ' ')
# Send broadcast ping on each interface
for interface in $interfaces; do
if [ "$interface" != "lo" ]; then
echo "Pinging on interface: $interface"
ping -I $interface -b 255.255.255.255 -c 3
fi
done
Já když říkám že píšu v C, tak mluvím o syntaxi jazyka. Že ty v tom vidíš standard a nedokázal bys napsat driver který musí zapsat na adresu 0 protože bys měl panickou hrůzu že to je undefined behaviour, to je tvoje mínus. Já jsem pragmatik a flexi. Kde to jde tak píšu portabilní kód, kde to nejde tak platform specific. A jestli tomu říkáš že nepíšu v C, tak si tomu tak říkej, je mě to celkem šumák. Asi vlastně nemám dále co bych tady k diskuzi přispěl, jsem diskvalifikován se o C vůbec bavit, protože dělám embedded věci. Oukej.Ale to se týká i embedded. I v embedded musíš řešit, že je dereference null pointeru undefined behavior. Dám ti praktický příklad. Jsou mikrokontroléry, které mají RAM v paměťové mapě od adresy 0, takže adresa 0 je naprosto validní pointer do RAM. Co s tím? Vyřeší se to tak, že se RAM zadefinuje od adresy 1 a adresa 0 se ignoruje, abychom se vyhnuli problémům s dereferencí null pointeru. Přijdeme o jeden bajt RAM na mikrokontroléru, ale to je nízká cena za vyřešení problémů s adresou 0 a undefined behavior.
Zápis přes pointer na adresu v paměti je naprosto standardní věc v C. To jenom ty zase musíš vytahovat nějaké speciality jako adresa 0 abys ukázal že jsi věčný troublemaker. Good jobJá jen cituji C standard, kde je explicitně uvedeno, že dereference null pointeru je undefined behavior. Rozumím tomu, že C standard nemáš přečtený a nevíš to. Nerozumím ale tomu, proč si pořád v opozici a snažíš se tvrdit, že zápis na jakoukoliv adresu přes pointer je v pohodě? Není to v pohodě, zápis na adresu 0 je dle C standardu undefined behavior. Ve chvíli, kdy to uděláš, tak od toho C standard dává ruce pryč a takový program může dělat cokoliv.
Píšu v C. Kde mám platform/compiler specific věci, tak použiju #ifdef a do poslední #else větve dám error "not implemented" a nechám toho kdo to někdy bude v budoucnu potřebovat, aby ty #else větve dopsal. Nebudu paralyzovat celý vývoj jenom kvůli tomu abych všem linuxákům vyhověl. Za to mě zákazník neplatí.Nepíšeš v C. Ve chvíli, kdy uděláš dereferenci null pointeru nebo jiné undefined behavior, tak od toho C standard dává ruce pryč. Na některých platformách takové věci můžou dávat smysl, ale vždy musíš explicitně zdůraznit, že se jedná o platformově závislou věc, kterou musíš speciálně řešit, např. nějakými flagy překladače. Ty to tady prezentuješ jako něco normálního, ale děláš je pravý opak, pohybuješ se mimo C stadard a musíš to záplatovat nějakými ohýbáky.
To mě ale nezajímá, mě zajíma jaký bude strojový kód a co program dělá a jestli dělá to co chci.V pořádku, ale neříkej potom, že píšeš v C. Nepíšeš totiž v C, ale v nějakém vrid dialektu, kdy jsou tvoje programy funkční jen s konkrétním nastavením překladače na konkrétní platformě.
Prostě si překladač nastavím jak potřebuju.Můžeš prohlásit, že dereference pointeru není undefined behavior. Můžeš i zkusit donutit překladač, aby při dereferenci null pointeru dělal něco definovaného. Nemáš pak ale validní C program. Máš program, který je dle C standardu nefunkční, standard říká, že nedefinuje jeho chování.
To nema s GCC nic společného. Takhle se psalo jestě než nějaký GCC vůbec existoval. A ani to nemá nutně nic společného s adresou 0. Prostě obecně když mám pointer a přectu přes něj nebo zapíšu, tak čtu nebo zapisuju z nějaké adresy v paměti která odpovídá hodnotě pointeru. Tady nic nestandardního není.Pořád tomu nerozumíš. Nevadí, zkusím to vysvětlit znovu. null pointer (adresa 0) se v C standardu ošetřuje speciálně. C standard explicitně říká, že dereference null pointeru je undefined behavior. Tozn. pokud máš v C programu čtení nebo zápis adresy 0, překladač s tím může udělat cokoliv (a taky dělá). Může to ignorovat, může vygenerovat neplatnou instrukci, může to dokonce i fyzicky provést. Jakékoliv chování, včetně všech zmíněných, je při dereferenci null pointeru legální.