Je jazyk C skutočne ťažký?

Re:Je jazyk C skutočne ťažký?
« Odpověď #90 kdy: 05. 06. 2025, 22:19:29 »
Ccko, narozdil od mnoha vsemoznych frikulinksych kravovin, po kterych za par let pes nestekne, dela presne to, co napises.
Jenže pokud nejsi velmi zkušený programátor, tak to znamená, že to velmi často dělá něco jiného, než chceš.


xyz

  • ****
  • 282
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #91 kdy: 05. 06. 2025, 23:27:04 »
Ccko, narozdil od mnoha vsemoznych frikulinksych kravovin, po kterych za par let pes nestekne, dela presne to, co napises.
Jenže pokud nejsi velmi zkušený programátor, tak to znamená, že to velmi často dělá něco jiného, než chceš.

Nerozumim. Muzes dat nejaky priklad? Proc by mel delat _velmi casto_ neco jineho nez chci, kdyz ten jazyk je jednoduchy?



Zopper

  • *****
  • 917
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #92 kdy: 05. 06. 2025, 23:49:17 »
Ccko, narozdil od mnoha vsemoznych frikulinksych kravovin, po kterych za par let pes nestekne, dela presne to, co napises.
Jenže pokud nejsi velmi zkušený programátor, tak to znamená, že to velmi často dělá něco jiného, než chceš.

Nerozumim. Muzes dat nejaky priklad? Proc by mel delat _velmi casto_ neco jineho nez chci, kdyz ten jazyk je jednoduchy?
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Re:Je jazyk C skutočne ťažký?
« Odpověď #93 kdy: 06. 06. 2025, 00:50:52 »
Není to jedinná varianta. Lze definovat makro a na platforme ktera nepodporuje signed aritmetic right shift se da jeho chovani simulovat.
Tak to jste me s tim test_sars pekne nahlodal. Mam ve sve helper knihovne tuto variantu
Kód: [Vybrat]
int asr(int x, int n)
{
    return (x >= 0) ? (x >> n) : ((x >> n) | (~((~0U) >> n)));
}
ktera je nezavisla na posuvu (arith/log), presne z toho duvodu, ze jsem nenasel elegantni zpusob, jak v compile time detekovat implementaci >>. Optimalizace v gcc i clang si s tim neporadi a konci to vzdy na sar + shr. Nastesti jsem to nikdy nepotreboval.

Re:Je jazyk C skutočne ťažký?
« Odpověď #94 kdy: 06. 06. 2025, 14:35:19 »
Já bych možná jen zmínil, že přestože jsem tu a tam historicky něco malého napsal, zhusta v céčku, tak shift na signed integer jsem co pamatuju nikdy nepotřeboval :-) takže ponaučení původnímu tazateli: jestli chcete tak se céčka bojte, ale ne kvůli shiftu se znaménkem :-)


Re:Je jazyk C skutočne ťažký?
« Odpověď #95 kdy: 06. 06. 2025, 15:16:21 »
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Mnohdy používají jen zbytečně komplikovaný přístup, kdy alokace spravují jednotlivě místo toho, aby to dělali hromadně.

Kdyby ten kód napsali jednodušeji, tak by měli méně problémů.

BoneFlute

  • *****
  • 2 043
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #96 kdy: 06. 06. 2025, 21:25:17 »
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Mnohdy používají jen zbytečně komplikovaný přístup, kdy alokace spravují jednotlivě místo toho, aby to dělali hromadně.

Kdyby ten kód napsali jednodušeji, tak by měli méně problémů.

A není to náhodou právě to, o co jde? Jazyk, který tě prostřílí jak řešeto jen proto, že nejsi dost dobrej...?

Ink

  • *****
  • 686
    • Zobrazit profil
    • E-mail
Re:Je jazyk C skutočne ťažký?
« Odpověď #97 kdy: 07. 06. 2025, 07:57:11 »
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Mnohdy používají jen zbytečně komplikovaný přístup, kdy alokace spravují jednotlivě místo toho, aby to dělali hromadně.

Kdyby ten kód napsali jednodušeji, tak by měli méně problémů.

Existuje na to nějaký dokument, který by popisoval "best practice" v takových případech? Ideálně s poukázáním na konkrétní historické incidenty?

Re:Je jazyk C skutočne ťažký?
« Odpověď #98 kdy: 07. 06. 2025, 09:55:52 »
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Mnohdy používají jen zbytečně komplikovaný přístup, kdy alokace spravují jednotlivě místo toho, aby to dělali hromadně.

Kdyby ten kód napsali jednodušeji, tak by měli méně problémů.

Existuje na to nějaký dokument, který by popisoval "best practice" v takových případech? Ideálně s poukázáním na konkrétní historické incidenty?

Nevím o tom.

Sám za sebe bych řekl: (1) preferovat statickou alokaci, (2) pokud nejde statická alokace preferovat arena alokátory nebo pooly, (3) pokud do nějaké struktury dávám ukazatel, tak ta struktura by neměla mít delší životnost než to, na co ukazuje ukazatel, (4) místo ukazatelů používat handly (z článku Handles are the better pointers), zejm. pokud si nejsem jistý životností objektů.

BoneFlute

  • *****
  • 2 043
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #99 kdy: 07. 06. 2025, 15:05:47 »
V CVE databázích je těch příkladů je spousta. Pokud to ani projekty jako Linux Kernel nebo GNU Coreutils nedokážou nedělat chyby při práci s pamětí, tak tím hůř se tomu ubrání někdo bez spousty praxe a citu.

Mnohdy používají jen zbytečně komplikovaný přístup, kdy alokace spravují jednotlivě místo toho, aby to dělali hromadně.

Kdyby ten kód napsali jednodušeji, tak by měli méně problémů.

Existuje na to nějaký dokument, který by popisoval "best practice" v takových případech? Ideálně s poukázáním na konkrétní historické incidenty?

Nevím o tom.

Sám za sebe bych řekl: (1) preferovat statickou alokaci, (2) pokud nejde statická alokace preferovat arena alokátory nebo pooly, (3) pokud do nějaké struktury dávám ukazatel, tak ta struktura by neměla mít delší životnost než to, na co ukazuje ukazatel, (4) místo ukazatelů používat handly (z článku Handles are the better pointers), zejm. pokud si nejsem jistý životností objektů.

Co mi to jen připomíná...

Re:Je jazyk C skutočne ťažký?
« Odpověď #100 kdy: 08. 06. 2025, 01:51:13 »
Ccko, narozdil od mnoha vsemoznych frikulinksych kravovin, po kterych za par let pes nestekne, dela presne to, co napises.
Jenže pokud nejsi velmi zkušený programátor, tak to znamená, že to velmi často dělá něco jiného, než chceš.

Nerozumim. Muzes dat nejaky priklad? Proc by mel delat _velmi casto_ neco jineho nez chci, kdyz ten jazyk je jednoduchy?
Tak schválně, co dělá tenhle nevinně vypadající kus kódu :
Kód: [Vybrat]
    for (int i = 0; i < 4; ++i)
        printf( "%d\n", i*1000000000 );

Odpověď zní že se může stát úplně cokoliv. :o V závislosti na platformě, překladači, náladě nosních démonů a fázi měsíce třeba :
- Vypíše to 4 čísla, které by člověk čekal. (obvykle debug, nebo staré překladače)
- Přeloží se to na nekonečnou smyčku. (novější překladače s optimalizacema)
- Vyoptimalizuje se to do pryč a vezme to ssebou půl programu. (pro tenhle konkrétní kód jsem to teda nepozoroval, ale je to legální a zažil jsem něco dost podobného)

Zkus tohle chování vysvětlit. Pokud možno _jednoduše_, když je C jednoduchý jazyk.  8)

Re:Je jazyk C skutočne ťažký?
« Odpověď #101 kdy: 08. 06. 2025, 05:36:03 »
Zkus tohle chování vysvětlit. Pokud možno _jednoduše_, když je C jednoduchý jazyk.  8)

Když to přeložím bez optimalizací - na gcc 15.1, vypíše to 4 čísla. Když to zkusím s optimalizací

dostanu zřetelný warning:

<code>
    test.c: In function ‘main’:
    test.c:7:9: warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]
        7 |         printf( "%d\n", i*1000000000 );
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test.c:6:20: note: within this loop
        6 |  for (int i = 0; i < 4; ++i)
          |                  ~~^~~
</code>

Re:Je jazyk C skutočne ťažký?
« Odpověď #102 kdy: 08. 06. 2025, 05:49:20 »
Zkus tohle chování vysvětlit. Pokud možno _jednoduše_, když je C jednoduchý jazyk.  8)

Když to přeložím bez optimalizací - na gcc 15.1, vypíše to 4 čísla. Když to zkusím s optimalizací

dostanu zřetelný warning:

<code>
    test.c: In function ‘main’:
    test.c:7:9: warning: iteration 3 invokes undefined behavior [-Waggressive-loop-optimizations]
        7 |         printf( "%d\n", i*1000000000 );
          |         ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    test.c:6:20: note: within this loop
        6 |  for (int i = 0; i < 4; ++i)
          |                  ~~^~~
</code>

Je to docela dobře vysvětlené https://stackoverflow.com/questions/24296571/why-does-this-loop-produce-warning-iteration-3u-invokes-undefined-behavior-an .

Holt optimalizace v C jsou opravdu agresivní - a opravdu se v Cčku nevyplatí ignorovat warningy

Re:Je jazyk C skutočne ťažký?
« Odpověď #103 kdy: 08. 06. 2025, 06:55:43 »
Je to docela dobře vysvětlené https://stackoverflow.com/questions/24296571/why-does-this-loop-produce-warning-iteration-3u-invokes-undefined-behavior-an .

Holt optimalizace v C jsou opravdu agresivní - a opravdu se v Cčku nevyplatí ignorovat warningy

Optimalizace založené na undefined behavior jsou, řekněmě, tak trochu za hranou. Formálně takovým optimalizacím nic nebrání (je to undefined, takže překladač může udělat cokoliv), nicméně obvykle nechceme, aby program dělal cokoliv. Nedávno vyšla docela hezká studie:

Exploiting Undefined Behavior in C/C++ Programs for Optimization: A Study on the Performance Impact

A její závěr je celkem jednoznačný: The results show that, in the cases we evaluated, the performance gains from exploiting UB are minimal. Furthermore, in the cases where performance regresses, it can often be recovered by either small to moderate changes to the compiler or by using link-time optimizations.

Konkrétně signed integer overflow zkoumají pod AO3 (vypnuli to pomocí -fwrapv) a rozdíly ve výkonu jsou zanedbatelné.

Re:Je jazyk C skutočne ťažký?
« Odpověď #104 kdy: 08. 06. 2025, 08:56:42 »
Konkrétně signed integer overflow zkoumají pod AO3 (vypnuli to pomocí -fwrapv) a rozdíly ve výkonu jsou zanedbatelné.

Ono je otázkou, co je dneska implementovatelné v překladači z pohledu zpětné kompatibility a očekávání uživatelů.

V každém případě moderní překladač důrazně upozorní, že je něco jinak, a je na vývojáři aby napsal kód bez warningu. V Postgresu kód s warningem nemá šanci se dostat do upstreamu, a co jsem se jako vývojář naučil, že warning v Cčku není něco, nad čím by se dalo mávnout rukou.