Nedeterministické chování programu při použití Clang

Dobrý den,
mám kód (viz. níže) který by podle mého měl být deterministický, u GCC tomu tak je, u Clang to hází pořád jiné výsledky.
Dělá chybu Clang, GCC nebo já? Kód je v C++, Clang je verze 9.0.1, GCC 9.3.1; oboje běží na Fedoře 31.
Kód: [Vybrat]
unsigned int getSum (std::string str) {
    unsigned int s;
    for (unsigned int c = 0; c < str.size (); c++) {
        s += str[c];
    }
    return s;
}
Děkuji za odpověď :)


Idris

  • *****
  • 2 286
    • Zobrazit profil
    • E-mail
Re:Nedeterministické chování programu při použití Clang
« Odpověď #1 kdy: 26. 04. 2020, 21:04:35 »
Chtělo by to proměnnou “s” při deklaraci inicializovat.

Re:Nedeterministické chování programu při použití Clang
« Odpověď #2 kdy: 26. 04. 2020, 21:07:51 »
Ok, funguje. Ale hází stejný výsledek jako GCC i před tím, takže Clang je drobek přísnější :)

_Jenda

  • *****
  • 1 554
    • Zobrazit profil
    • https://jenda.hrach.eu/
    • E-mail
Re:Nedeterministické chování programu při použití Clang
« Odpověď #3 kdy: 27. 04. 2020, 00:04:49 »
-Wall a ideálně ještě -Wextra -Wduplicated-cond -Wduplicated-branches -Wlogical-op -Wrestrict -Wnull-dereference -Wjump-misses-init -Wdouble-promotion -Wshadow a -pedantic :)

Kód: [Vybrat]
test.c: In function ‘main’:
test.c:3:5: warning: ‘s’ is used uninitialized in this function [-Wuninitialized]

Mimochodem chtěl jsem napsat -fsanitize=undefined, ale nějak mi ho to nechytne. Ale stejně to stojí za to znát. A -fsanitize=address, když už jsme u toho.
« Poslední změna: 27. 04. 2020, 00:10:21 od _Jenda »

Re:Nedeterministické chování programu při použití Clang
« Odpověď #4 kdy: 27. 04. 2020, 08:52:41 »
Ok, funguje. Ale hází stejný výsledek jako GCC i před tím, takže Clang je drobek přísnější :)
To není primárně o přísnosti. Jak GCC tak Clang při optimalizacích využívají nedefinované chování dost agresivně. V různých situacích se to může a nemusí projevit, protože jejich optimalizátory pracují každý trošku jinak. Výsledek může vypadat dost chaoticky. Například tu funkci můžou "rozbít" úpravy na úplně jiném místě v kódu.

Rozhodně bych se nespoléhal na to, že GCC (nebo i jakýkoliv jiný překladač) se bude kolem neinicializovaných proměnných chovat nějak příčetně. Že ta funkce vrátí nějaký binec je ještě celkem intuitivní chování, ale už jsem viděl i docela divoké věci.