Bestimmt dürfte einigen von euch die Seite c-faq.com bekannt sein.
Ich glaube Krishty hatte die irgendwann mal gepostet - eine 1:1 Kopie des Inhaltes, des gleichnamigen Buches - und dieses gilt - soviel ich mitbekommen habe - ja als "echtes Werk" und Klassiker (weshalb mich Zweifel zu meinen Schlussfolgerungen beschleichen).
Jedenfalls bin ich in Kapitel 16, Frage 7 auf ein Snippet gestossen, das - wie ich glaube - eigentlich UB sein müsste.
https://c-faq.com/strangeprob/ptralign.html
Code: Alles auswählen
unsigned char *p = buf;
s.c = *p++;
s.i32 = (long)*p++ << 24;
s.i32 |= (long)*p++ << 16;
s.i32 |= (unsigned)(*p++ << 8);
s.i32 |= *p++;
s.i16 = *p++ << 8;
s.i16 |= *p++;
Ohne den cast zu long würde der Bitshift-Operator ja zu int promoten (Ist das die "Ganzzahlerweiterung" zu deutsch?). Doch da dieser hier - in diesem Setting nur 16 Bit aufweist (wie der Autor ja sinnvollerweise auch anmerkt), würde das nicht ausreichen.
Was mir nicht einleuchtet:
Wenn jetzt aber der Wert unter dem zweiten unsigned char grösser als 127 wird, dann muss auch das höchstwertigste Bit in diesem char gesetzt sein. Folglich resultiert dann aber ein Überlauf beim Links-Shift um 24 Bit. (Der erste char, auf den p zeigt wird ja einfach s.c zugewiesen. Hier geht es folglich um den zweiten bis fünften char).
Müsste man da nicht zu unsigned long casten?
Fast der selbe Fehler war doch in der SDL, den Andrew Kelley kürzlich gefunden hatte (danke Krishty für die Erläuterung).
Wir hatten das Thema vor ein paar Wochen kurz im IRC besprochen und ich habe Steve Summit daraufhin angemailt.
Er hat mir jedoch bis heute nicht geantwortet - vielleicht weil wir etwas banales übersehen hatten?