Forum: PC-Programmierung MSVC 19 broken


von Wilhelm M. (wimalopaan)


Lesenswert?

Interessante Beobachtung:

folgendes Programm
1
#include <stdio.h>
2
3
int main() {
4
  puts("A banner with the strange device 'Migicative'!");
5
  puts("A banner with the strange device 'Borabigate'!");
6
}

ergibt zweimal den ersten Text mit MSVC und `-O1` ;-)

Quelle: https://quuxplusone.github.io/blog/2022/12/31/mid-snow-and-ice

von Oliver S. (oliverso)


Lesenswert?

Wilhelm M. schrieb:
> MSVC und `-O1`

Würde mich wundern, wenn der MSVC '-O1' versteht ;)

Ansonsten klingt das stark nach Xerox...
https://www.youtube.com/watch?v=7FeqF1-Z1g0

Oliver

: Bearbeitet durch User
von Kaj (Gast)


Lesenswert?

Oliver S. schrieb:
> Ansonsten klingt das stark nach Xerox
Was hat der Compiler mit dem Drucker zu tun?

von Udo K. (udok)


Lesenswert?

Oliver S. schrieb:
>> MSVC und `-O1`
>
> Würde mich wundern, wenn der MSVC '-O1' versteht ;)

Ist kein Problem, der MSVC versteht auch -O2 und -c :-)

Das mit den Strings ist aber wirklich ein Bug, der in allen Versionen 
drinnen ist.
Meine Vermutung: der MSVC macht eine Checksumme über die Strings,
und es gibt eine gewisse Wahrscheinlichkeit, dass die gleich ist, obwohl 
die Strings unterschiedlich sind.
Wenn du das Read-Only String Pooling mit -GF- ausmachst, geht es...

: Bearbeitet durch User
von Wilhelm M. (wimalopaan)


Lesenswert?

Udo K. schrieb:
> Oliver S. schrieb:
>>> MSVC und `-O1`
>>
>> Würde mich wundern, wenn der MSVC '-O1' versteht ;)
>
> Ist kein Problem, der MSVC versteht auch -O2 und -c :-)
>
> Das mit den Strings ist aber wirklich ein Bug, der in allen Versionen
> drinnen ist.
> Meine Vermutung: der MSVC macht eine Checksumme über die Strings,
> und es gibt eine gewisse Wahrscheinlichkeit, dass die gleich ist, obwohl
> die Strings unterschiedlich sind.
> Wenn du das Read-Only String Pooling mit -GF- ausmachst, geht es...

Schön, dass Du die Quelle ins deutsche übersetzt hast ;-)

von DPA (Gast)


Lesenswert?

Ich weiss schon, warum ich den scheiss compiler nicht verwende ;)

von Udo K. (udok)


Lesenswert?

Wilhelm M. schrieb:
> Schön, dass Du die Quelle ins deutsche übersetzt hast ;-)

Schön, dass die Quelle mit meiner Meinung übereinstimmt :-)

von Udo K. (udok)


Lesenswert?

DPA schrieb:
> Ich weiss schon, warum ich den scheiss compiler nicht verwende ;)

Eigentlich ist der Compiler ziemlich brauchbar.  Um den Bug zu triggern, 
musst du schon sehr lange rumprobieren, und andere Compiler haben halt 
andere Bugs...

von c-hater (Gast)


Lesenswert?

Udo K. schrieb:

> Eigentlich ist der Compiler ziemlich brauchbar.  Um den Bug zu triggern,
> musst du schon sehr lange rumprobieren, und andere Compiler haben halt
> andere Bugs...

Oder sogar denselben (prinzipiell)... In unzähligen Sprachen und 
Compilern werden Hashes verwendet und natürlich kann man dafür genau 
solche Kollisionen konstruieren.

Ist halt ein trade-off: Je kürzer der Hash, desto effizienter wird der 
Code, aber gleichzeitig steigt halt leider auch die Gefahr von 
Kollisionen.

Niemand, der wirklich programmieren kann, wird sich darüber ernsthaft 
wundern.

von DPA (Gast)


Lesenswert?

Entweder man nimmt einen schön langen und sicheren hash, (z.B. sha256), 
und nimmt bewusst in kauf, dass irgendwo einmal in 1 von 2^256 fällen 
oder so eine Kollision passiert, oder man checkt nicht nur den hash, 
sondern nutzt den nur für den Lookup, und check dann auch noch den 
ganzen Inhalt. (Genau darum haben hash maps üblicherweise buckets.)

Niemand, der wirklich programmieren kann, verwendet unsichere kurze 
hashes und checkt gleichzeitig nicht nochmal nach, ob es wirklich 
übereinstimmt. Das ist einfach nur falsch und unverantwortlich.

von Udo K. (udok)


Lesenswert?

DPA schrieb:
> Niemand, der wirklich programmieren kann, verwendet unsichere kurze
> hashes und checkt gleichzeitig nicht nochmal nach, ob es wirklich
> übereinstimmt. Das ist einfach nur falsch und unverantwortlich.

Der Algorithmus ist > 30 Jahre alt.  Bisher ist es keinem aufgefallen. 
Das ist auch kein Hash für eine Tabelle, sondern das PE Exe Format 
hat(te) eine Beschränkung für die Länge der externen Symbole.
Lange Strings - die extern sichtbar sind - werden als 
"BIN_EIN_LANGER_STRING?MEIN_HASH_WERT?" oder so ähnlich kodiert.
Mehr ist da nicht dran. Wenn man nicht die modernen heute üblichen 
Optimierungen verwendet, dann schreit der Linker sowieso wegen doppelt 
definierten Symbolen...

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Oder sogar denselben (prinzipiell)... In unzähligen Sprachen und
> Compilern werden Hashes verwendet und natürlich kann man dafür genau
> solche Kollisionen konstruieren.
> Niemand, der wirklich programmieren kann, wird sich darüber ernsthaft
> wundern.

Klar, und genau deshalb werden normalerweise Vorkehrungen getroffen, um 
solche Kollisionen korrekt zu behandeln. Was würde wohl passieren, wenn 
Hashtabellen z.B. in einer Datenbank gerne mal das falsche Ergebnis 
zurückliefern würden, weil zwei Einträge blöderweise den selben Hash 
haben?

> Ist halt ein trade-off: Je kürzer der Hash, desto effizienter wird der
> Code, aber gleichzeitig steigt halt leider auch die Gefahr von
> Kollisionen.

Ist das deine Vorgehensweise? Abwägung, wie viele Fehler man in Kauf 
nehmen kann, um noch ein paar Bytes extra rauszuholen?

Udo K. schrieb:
> Lange Strings - die extern sichtbar sind - werden als
> "BIN_EIN_LANGER_STRING?MEIN_HASH_WERT?" oder so ähnlich kodiert.
> Mehr ist da nicht dran.

Ja, und das ist ein konzepzioneller Fehler, weil eben auch verschiedene 
Strings den selben Hash-Wert haben können und damit dann das selbe 
Symbol bekommen.

> Wenn man nicht die modernen heute üblichen Optimierungen verwendet, dann
> schreit der Linker sowieso wegen doppelt definierten Symbolen...

Wohl eher nicht, denn das hätte zur Folge, dass man in einem Program nie 
zwei gleiche String-Literals haben könnte.

von Wilhelm M. (wimalopaan)


Lesenswert?

c-hater schrieb:
> Niemand, der wirklich programmieren kann, wird sich darüber ernsthaft
> wundern.

So ein Blödsinn ... und das von Dir (falls Du es bist).

Hashfunktionen sind meistens kollisionsbehaftet, weil sie meistens 
injektiv sind (sein müssen). In diesem Fall ist das so. Ein korrekter 
Hash-Algorithmus wird daher eine Kollisionslösungsstragie haben (meisten 
über Hash-Buckets), damit er kollisionsfrei ist.

Mir ist völlig unverständlich, wie man so einen Mist in einen Compiler 
einbauen kann bzw. aktiviert lassen kann, auch wenn es irgendwie 
abschaltbar ist.

von Nano (Gast)


Lesenswert?

Wilhelm M. schrieb:
> Mir ist völlig unverständlich, wie man so einen Mist in einen Compiler
> einbauen kann bzw. aktiviert lassen kann, auch wenn es irgendwie
> abschaltbar ist.

Es ist eher verwunderlich, warum das die Defaulteinstellung ist, gerade 
wenn es abschaltbar ist, hätte die sichere vorsichtige Einstellung die 
Defaulteinstellung sein müssen und die unsichere die per Option 
zuschaltbare.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.