Nie, prawdopodobnie miksujesz różne rzeczy.
Rygorystyczne reguły dotyczące aliasów nie mają absolutnie nic wspólnego ze standardem C99. Rygorystyczne zasady aliasingu są zakorzenione w częściach standardu, które były obecne w C i C++ od początku [standaryzowanych] razy. Klauzula, która zabrania dostępu do obiektu jednego rodzaju przez lwartości innego typu, występuje w C89/90 (6.3), a także w C++ 98 (3.10/15). Na tym polega ścisłe aliasing, nie więcej, nie mniej. Po prostu nie wszystkie kompilatory chciały (lub ośmieliły się) go wymusić lub na nim polegać. Zarówno języki C, jak i C++ są czasem używane jako języki "wysokiego poziomu", a ścisłe reguły aliasingu często kolidują z takimi zastosowaniami. To właśnie GCC dokonało tego śmiałego posunięcia i postanowiło zacząć polegać na regułach ścisłego aliasingu w optymalizacjach, często pobierając skargi z tych "montażowych" typów.
To prawda, że najprostszym sposobem złamania restrykcyjnych reguł aliasingu w C++ jest reinterpret_cast
(i oczywiście obsada w stylu C). Jednakże static_cast
mogą być również stosowane do tego celu, gdyż pozwala, aby przerwać ścisłe wygładzanie za pomocą void *
jako typ pośredni w „łańcuch” cast
int *pi;
...
double *pd = static_cast<double *>(static_cast<void *>(pi));
const_cast
nie rozkłada ścisłego aliasingu w kompilatorze zasadami.
Co do C99 ... To, co wprowadził C99, to kwalifikator restrict
. Jest to bezpośrednio związane z aliasingiem, ale nie jest to tak zwane ścisłe aliasing jako takie.
Masz rację, myślałem C99 'ograniczać' słowo kluczowe, zamiast ścisłego aliasingu. Z jakiegoś powodu utkwiło mi to w głowie ("C99" + "ścisłe aliasing"). –
Więc czym dokładnie jest ta klauzula?Czy oznacza to, że każdy kod C89/C99/C++ 98, który łamie ścisłe reguły aliasingu, jest technicznie niepoprawny (z wyłączeniem specyficznych dla kompilatora przełączników, takich jak -fno-strict-aliasing)? –
@Checkers: Dodałem numery do mojej odpowiedzi. I tak, kod łamiący zasady ścisłego aliasingu wykazuje niezdefiniowane zachowanie, również w C89 i C++ 98. – AnT