MSVC 19 broken

OP #7303952
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

Gast #7304236
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...

OP #7304239
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 ;-)

Gast #7304391
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.

Gast #7304436
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.

Gast #7304849
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...

#7306124
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.

OP #7306142
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.

Gast #7306183
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren