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

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #135 kdy: 10. 06. 2025, 17:05:02 »
A ještě si musí všimnout, že se mu signed a unsigned potkaly. Stačí aby to x nebylo deklarované hned vedle toho ifu a je to.

Ne, on by si neměl všimnout. On jde něco porovnávát, tak musí vědět co jde porovnávat. Nemůžu přece něco porovnávat pokud nevím jakého to je datového typu a tedy s čím to můžu (kompatibilní datové typy) porovnat. Jak můžu bez těchto informací vůbec jít něco porovnávat?

Citace
Nějaký důvod tam bude, když MSVC i clang mlčí jak partizáni. A i gcc potřebuje -Wall, jinak drží hubu.

U jiných věcí mi překladače nadávají daleko ochotněji. Tenhle warning z nich člověk musí spíš páčit.
Warning na to ale je - na všechny porovnání signed a unsigned proměnných/konstant dostaneš warning. Critical mission politika v tomto ohledu je zastaralá, asi vychází z dob kdy kompilátory toto hlásit neuměly, nebo nevím proč raději nepoužít warningy a místo toho všude rvát inty, kde zase mohou vznikat jiné chyby které by s unsigned nebyly.


vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #136 kdy: 10. 06. 2025, 17:23:05 »
Je sranda když si někdo stežuje na "undefined behaviour", ale přitom píše kód stylem "wishful programming", kdy něco očekává - že jazyk by se měl chovat tak nebo onak a je to chyba jazyka když tomu tak není.

Tak na jednu stranu je špatně undefined behaviour a na druhou stranu defined behaviour, kde -1 se převede na unsigned a pak porovná, je taky špatně. Tak už si vyberte :)

Re:Je jazyk C skutočne ťažký?
« Odpověď #137 kdy: 10. 06. 2025, 17:25:19 »
A ještě si musí všimnout, že se mu signed a unsigned potkaly. Stačí aby to x nebylo deklarované hned vedle toho ifu a je to.

Ne, on by si neměl všimnout. On jde něco porovnávát, tak musí vědět co jde porovnávat. Nemůžu přece něco porovnávat pokud nevím jakého to je datového typu a tedy s čím to můžu (kompatibilní datové typy) porovnat. Jak můžu bez těchto informací vůbec jít něco porovnávat?
Víte co mě zaráží? Že si nějaký vývojář ani po 17 letech neuvědomuje, jak jednoduché je udělat chybu. Že my lidi udržíme v hlavě najednou jen cca 10 věcí. A každá věc, co za nás nehlídá překladač a musíme ji hlídat my nám z té konečné mentální kapacity užírá.
Citace
Citace
Nějaký důvod tam bude, když MSVC i clang mlčí jak partizáni. A i gcc potřebuje -Wall, jinak drží hubu.

U jiných věcí mi překladače nadávají daleko ochotněji. Tenhle warning z nich člověk musí spíš páčit.
Warning na to ale je - na všechny porovnání signed a unsigned proměnných/konstant dostaneš warning. Critical mission politika v tomto ohledu je zastaralá, asi vychází z dob kdy kompilátory toto hlásit neuměly, nebo nevím proč raději nepoužít warningy a místo toho všude rvát inty, kde zase mohou vznikat jiné chyby které by s unsigned nebyly.
Je v jen v jednom ze tří nejpoužívanějších překladačů. A ani v něm není zapnutý by default. Takový warning spíš není než je.

Re:Je jazyk C skutočne ťažký?
« Odpověď #138 kdy: 10. 06. 2025, 17:32:21 »
Je sranda když si někdo stežuje na "undefined behaviour", ale přitom píše kód stylem "wishful programming", kdy něco očekává - že jazyk by se měl chovat tak nebo onak a je to chyba jazyka když tomu tak není.

Tak na jednu stranu je špatně undefined behaviour a na druhou stranu defined behaviour, kde -1 se převede na unsigned a pak porovná, je taky špatně. Tak už si vyberte :)
Ano špatně je nedefinované i blbě definované chování.  Zkuste chvíli psát v třeba assembleru. Nepotkal jsem žádný jazyk, který by blbé inty dokázal zkomplikovat tak, jako to udělalo C.

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #139 kdy: 10. 06. 2025, 17:46:53 »
Tady tuto věc ale překladač hlídá, sic ne by default.

Tak ono to je asi prostě o tom jak kdo přemýšlí. Nedávno jsem četl jak jeden britský turista mluvil s jedním indánem, bavili se o lovu a ten brit řekl jednoduše že vystřelil. A to tomu indánovi přišlo strašně podivné. Protože to je pro ně uplně neexistující pojem. Oni tak nepřemýšlí. Oni když řeknou že vystřelili, tak u toho vždycky řeknou na co mířili a co tou střelou chtěli dokázat - jaký měla účel. A tady vidím podobnost. Prostě já když jdu něco porovnávat, tak vím co jdu porovnávat a s čím a bez toho to nemůžu ani udělat. Nemůžu "jen tak porovnat". Porovnávám vždy něco s něčím.

No a pokud je něčí záměr úplný a jen se třeba přeťukl ve znaménku nebo operátoru, tak oukej, ale ať to nenazývá že tam je nějaké překvápko. Překvápko = neznalost... A to je úplně něco jiného než že někdo udělá překlep nebo jinou chybu.

Dále nechápu to s tím assemblerem. C přesně odpovídá tomu jak jsou věci v assembleru. Je to de-facto portabilní assembler. A právě ten kdo prozkoumá věci v C až na úroveň asembleru, tak ten má pak v těch věcech jasno a žádná mentální zátěž to pro něj už není. Mentální zátěž je, když v tom jasno právě nemá a musí to pořád vyhodnocovat.


Zopper

  • *****
  • 901
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #140 kdy: 10. 06. 2025, 19:59:02 »
A ještě si musí všimnout, že se mu signed a unsigned potkaly. Stačí aby to x nebylo deklarované hned vedle toho ifu a je to.

Ne, on by si neměl všimnout. On jde něco porovnávát, tak musí vědět co jde porovnávat. Nemůžu přece něco porovnávat pokud nevím jakého to je datového typu a tedy s čím to můžu (kompatibilní datové typy) porovnat. Jak můžu bez těchto informací vůbec jít něco porovnávat?
Což v reálném světě funguje asi tak do situace, kdy se to porovnání napsalo před rokem, porovnává se nějaký atribut ve struktuře nebo jiném netriviálním datovém typu, a někdo jiný o rok později v té struktuře změní ten int na unsigned int. A aby to chytlo -Wall, to by na tom projektu muselo pracovat tak pět lidí pod tvrdým dohledem, kdy jakýkoliv warning je špatně, a ne pět set, s přicmrdáváním někde z Indie, kdy ten jeden důležitý warning se utopí v hromadě jiných. A jasně, podobné věci se dějí bez ohledu na jazyk. Akorát jak tahle diskuze ukazuje v tom C je prostě o dost víc možností, jak si ustřelit vlastní nohu a při tom udělat bezpečnostní zranitelnost.

Re:Je jazyk C skutočne ťažký?
« Odpověď #141 kdy: 10. 06. 2025, 21:26:02 »
Večerní C kvíz. Proč se tento program chová tak divně a proč -Wall nic neřekne? Kdo to vyřeší, dostane odkaz do gcc bugzilly ;)
Kód: [Vybrat]
#include <stdio.h>

int main()
{
    static int array[2] = {0, 1};

    int *a = &array[1];
    unsigned i = 0;
    a += i - 1;
    printf("%d\n", *a);

    return 0;
}

Nejprve to přeložme a spusťme bez optimalizací:
Kód: [Vybrat]
gcc -Wall main.c -o test
./test
Neoprávněný přístup do paměti (SIGSEGV)

A teď s optimalizacemi:
Kód: [Vybrat]
gcc -O2 -Wall main.c -o test
./test
0

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #142 kdy: 10. 06. 2025, 21:28:52 »
A ještě si musí všimnout, že se mu signed a unsigned potkaly. Stačí aby to x nebylo deklarované hned vedle toho ifu a je to.

Ne, on by si neměl všimnout. On jde něco porovnávát, tak musí vědět co jde porovnávat. Nemůžu přece něco porovnávat pokud nevím jakého to je datového typu a tedy s čím to můžu (kompatibilní datové typy) porovnat. Jak můžu bez těchto informací vůbec jít něco porovnávat?
Což v reálném světě funguje asi tak do situace, kdy se to porovnání napsalo před rokem, porovnává se nějaký atribut ve struktuře nebo jiném netriviálním datovém typu, a někdo jiný o rok později v té struktuře změní ten int na unsigned int. A aby to chytlo -Wall, to by na tom projektu muselo pracovat tak pět lidí pod tvrdým dohledem, kdy jakýkoliv warning je špatně, a ne pět set, s přicmrdáváním někde z Indie, kdy ten jeden důležitý warning se utopí v hromadě jiných. A jasně, podobné věci se dějí bez ohledu na jazyk. Akorát jak tahle diskuze ukazuje v tom C je prostě o dost víc možností, jak si ustřelit vlastní nohu a při tom udělat bezpečnostní zranitelnost.

Tak základ je mít warningy zapnuté a mít projekt ve stavu že nedává žádný warning. To už je na projekt manažerovi aby to podchytil, kde mít warningy a jaké.

A jak by to teda mělo být správně? Warning nestačí? To se má celé C změnit protože se lidi strílejí do nohy? A co performance a všechno s tím spojené... zahodit?

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #143 kdy: 10. 06. 2025, 21:40:10 »
Večerní C kvíz. Proč se tento program chová tak divně a proč -Wall nic neřekne? Kdo to vyřeší, dostane odkaz do gcc bugzilly ;)
Kód: [Vybrat]
#include <stdio.h>

int main()
{
    static int array[2] = {0, 1};

    int *a = &array[1];
    unsigned i = 0;
    a += i - 1;
    printf("%d\n", *a);

    return 0;
}

Nejprve to přeložme a spusťme bez optimalizací:
Kód: [Vybrat]
gcc -Wall main.c -o test
./test
Neoprávněný přístup do paměti (SIGSEGV)

A teď s optimalizacemi:
Kód: [Vybrat]
gcc -O2 -Wall main.c -o test
./test
0

Další příklad "wishful programmingu". Proč máš i unsigned když chceš dělat signed aritmetiku a mít výsledek -1?

a += 0u - 1
což je to samé jako
a += 0xffffffff

Vysvětli proč jsi použil unsigned
« Poslední změna: 10. 06. 2025, 21:46:21 od vrit »

Re:Je jazyk C skutočne ťažký?
« Odpověď #144 kdy: 10. 06. 2025, 21:43:46 »
Další příklad "wishful programmingu". Proč máš i unsigned když chceš dělat signed aritmetiku a mít výsledek -1?
Ano, všichni víme, že ty bys žádnou podobnout chybu nikdy neudělal, ale kde je ten slibovaný warning, který měl být s -Wall vidět?

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #145 kdy: 10. 06. 2025, 21:47:40 »
Další příklad "wishful programmingu". Proč máš i unsigned když chceš dělat signed aritmetiku a mít výsledek -1?
Ano, všichni víme, že ty bys žádnou podobnout chybu nikdy neudělal, ale kde je ten slibovaný warning, který měl být s -Wall vidět?

Toto je normální runtime podtečení, proč by to mělo dávat warning?

Re:Je jazyk C skutočne ťažký?
« Odpověď #146 kdy: 10. 06. 2025, 21:55:23 »
Toto je normální runtime podtečení, proč by to mělo dávat warning?
Protože to má dát tento warning, ale z nějakého důvodu nedá. Pokračuj v řešení kvízu, jsi na dobré cestě ;)
Kód: [Vybrat]
main.c: In function ‘main’:
main.c:10:5: warning: array subscript 4294967296 is outside array bounds of ‘int[2]’ [-Warray-bounds]

vrit

Re:Je jazyk C skutočne ťažký?
« Odpověď #147 kdy: 10. 06. 2025, 22:22:18 »
Toto je normální runtime podtečení, proč by to mělo dávat warning?
Protože to má dát tento warning, ale z nějakého důvodu nedá. Pokračuj v řešení kvízu, jsi na dobré cestě ;)
Kód: [Vybrat]
main.c: In function ‘main’:
main.c:10:5: warning: array subscript 4294967296 is outside array bounds of ‘int[2]’ [-Warray-bounds]

Ne, k datům se přistupuje přes pointer, tak proč by to mělo psát že array out of bounds?

Re:Je jazyk C skutočne ťažký?
« Odpověď #148 kdy: 10. 06. 2025, 22:34:28 »
Ne, k datům se přistupuje přes pointer, tak proč by to mělo psát že array out of bounds?
gcc ví, že pointer je alias na to původní pole. V tomto kódu warning dostaneš:
Kód: [Vybrat]
#include <stdio.h>

int main()
{
    int array[2] = {0, 1};
    int *a = &array[1];
    a += 1;
    printf("%d\n", *a);

    return 0;
}
Kód: [Vybrat]
gcc -Wall -O2 main.c -o test
main.c: In function ‘main’:
main.c:8:5: warning: array subscript 2 is outside array bounds of ‘int[2]’ [-Warray-bounds]
    8 |     printf("%d\n", *a);
      |     ^~~~~~~~~~~~~~~~~~
main.c:5:9: note: at offset 8 into object ‘array’ of size 8
    5 |     int array[2] = {0, 1};
      |         ^~~~~

No ale v tom původním přikladu žádný warning není a navíc to bez optimalizací spadne, ale s optimalizacemi dává "správný" výsledek. Záhada, že?  ;)

Zopper

  • *****
  • 901
    • Zobrazit profil
Re:Je jazyk C skutočne ťažký?
« Odpověď #149 kdy: 10. 06. 2025, 22:38:07 »
Tak základ je mít warningy zapnuté a mít projekt ve stavu že nedává žádný warning. To už je na projekt manažerovi aby to podchytil, kde mít warningy a jaké.

A jak by to teda mělo být správně? Warning nestačí? To se má celé C změnit protože se lidi strílejí do nohy? A co performance a všechno s tím spojené... zahodit?
To, co tu tvrdíme už nějakou dobu. Nechat C jen tam, kde je to nezbytně nutné. A tam, kde chceš performance, ale není nutně důvod použít C, použít třeba Rust. Který dá +- podobný výkon, ale z principu vyloučí velmi časté chyby z C.

Proč lidi tolik trvají na tom, že i šroub musí zatlouct kladivem, jen proto, že je to o něco rychlejší, než najít ten šroubovák?  :D