TBAA funktioniert nicht mit C/C++.
Es gab ein schönes Ticket für einen Compiler-Bug im GCC
ca. 2010 2006, in dem die Entwickler langsam begriffen haben, dass ihr TBAA prinzipiell ungeeignet ist, und es dann als absurde Fehlinterpretation des Standards abgestritten haben. Daraufhin hat ein Kommitee-Mitglied gesagt
„ich war im Raum, als wir das entschieden haben, und es war in der Tat genau so gemeint!“. Muss ich mal raussuchen.
Die Notwendigkeit bei C ergibt sich aus
memcpy(),
memcmp() usw. – diese Funktionen basieren darauf, dass jedes Objekt mit
char * gealiast werden kann, damit sich die Bytes der Binärrepräsentation inspizieren lassen (wie auch immer sie dann aussehen).
Bei C++ ergibt sie sich natürlich aus Vererbung – einer Funktion
foo(Base *) kann ich einen Zeiger auf
Derived übergeben; der deklarierte Typ stimmt also nicht mit dem Laufzeittyp überein und durch Mehrfachvererbung können auch Adresse und Layout radikal verschieden sein.
Und, weniger natürlich, aus Placement
new. Beispiel (ich glaube, das war der GCC-Bug):
int var;
for(int i = 0; i < 123; i++) {
if(i & 1)
new (&var) int(42);
else
new (&var) float(42.f);
someFunction(var);
}
Bei jedem geraden Schleifendurchlauf ist
var ein
float und bei jedem ungeraden ein
int. In
someFunction() hat TBAA keine Chance, Aliasing aufzulösen. Bist du optimistisch, hast du einen Compiler-Bug. Bist du pessimistisch, hast du keine Optimierung mehr.
Edit: Hier ist das Ticket – viel Spaß beim Lesen.
Edit 2: Interessantes Zeug drin.
TBAA accounts for about 7-25% of alias disambiguations in the real world for C and C++ (combined). This is according to both papers published by Intel about ICC, papers published by MS about VC, papers published by IBM about XLC, and testing of Google's codebase with and without -fno-strict-aliasing (with the caveat that we know our codebase is not entirely strict aliasing safe)