AusgeBOOLt
« | 23 Mar 2019 | »Was für ein Drama! Boolsche Auswertung gab es in C natürlich schon immer.
Doch als C++ den Typen bool
als
elementaren Kernsprachen-Typen einführte, machte C diesen Schritt nicht mit,
hatte jedoch kurz danach die Idee, dieses Feature als typedef
im Header
stdbool.h
nachzuliefern.
Und heute suchte ich verzweifelt einen seltsamen Bug, der den Stack korrumpierte, der jedoch nur in Visual Studio 2005 und 2008, nicht jedoch im 2017 auftrat.
Und was der Grund? Natürlich der Typ bool
.
Nun, der Microsoft Teufel hatte aus
Gott weiß welchen Gründen die Compiler-Releases daran gehindert stdbool.h
mitauszuliefern und eine “natürliche” Brücke zwischen dem C++ Typen bool
und
dem C-Nachbau _Bool
aufzubauen.
Aus diesem Grund kompilierten viele moderne Bibliotheken nicht mit etwas älteren Microsoft Compilern.
Ein bekannter Workaround dafür ist, den Header stdbool.h
selbst
bereitzustellen, und eine gängige Variante davon ist:
So lange man C nur mit C Code betreibt und C++ Code nur mit C++, gibt es damit
auch keine Probleme.
Doch wehe, man definiert in C eine Struktur mit bool
Membern, die von einer
C++ Funktion instanziiert wird und dann an eine C Funktion per Pointer
übergeben wird, dann tanzen Korruptionen und andere Segmentationfaults durch
die Gegend.
Der Grund ist - wenn er erst erkannt wurde - denkbar einfach.
Weder C noch C++ definieren im Sprachstandard eine feste Größe für bool
und enum
, doch die Compiler Hersteller tun dies für ihre Implementierung.
Und bei Microsoft ist bool
ein Byte groß ohne Alignment, während
enum
Definitionen einem int
gleicht, also 4 Bytes lang sind.
Und schon erhält die gleich C-Struktur zwei unterschiedliche Aufbaupläne und ist in C++ kleiner als in C … somit stimmen die Speicheradressen nicht mehr und die Welt geht unter.
Lösung
Nun, mit der Änderung der stdbool.h
Implementierung auf:
ist das Problem auf binärer Ebene gelöst.
_Bool
und bool
sind damit in C und C++ genau ein Byte groß
und austauschbar, und die Zuweisung von enum
s auf unsigned char
wird zumindest vom MSVC
im C-Modus nicht (besonders schlimm)
angemeckert.
Schon witzig, dass ich jetzt seit Jahren mit dieser alten stdbool
Implementierung lebe, einige Fremdbibliotheken damit betreibe und noch nie
Probleme damit hatte.
Tja, offenbar, habe ich noch nie bool
Werte zwischen C und C++ damit
ausgetauscht.
Nun gut, dann wurde das ja auch mal Zeit!
Bonusfrage: Wie kam überhaupt es zu dem Szenario?
Antwort: Windows CE! Für was sonst braucht man denn solche uralten Compiler…