Я пытаюсь проверить часть своего кода на предмет строгих нарушений псевдонима, но похоже, что я что-то пропустил, пытаясь понять правило строгого псевдонима.
Представьте себе следующий код:
#include <stdio.h>
int main( void )
{
unsigned long l;
l = 0;
*( ( unsigned short * )&l ) = 1;
printf( "%lu\n", l );
return 0;
}
Классический и базовый пример. В GCC 4.9 (-Wall -fstrict-aliasing -Wstrict-aliasing -O3
) он фактически сообщает об ошибке:
dereferencing type-punned pointer will break strict-aliasing rules
Но следующие компилируются нормально:
#include <stdio.h>
int main( void )
{
unsigned long l;
unsigned short * sp;
l = 0;
sp = ( unsigned short * )&l;
*( sp ) = 1;
printf( "%lu\n", l );
return 0;
}
Насколько я понимаю, второй пример также нарушает правило сглаживания структуры.
Так почему он компилируется? Это проблема точности в GCC, или я что-то пропустил со строгим псевдонимом?
Я также нашел следующую тему: Почему для этого кода не генерируются предупреждения о строгом псевдониме?
Компиляция с -Wstrict-aliasing=2
или -Wstrict-aliasing=3
не имеет значения.
Но -Wstrict-aliasing=1
сообщает об ошибке во втором примере.
В документации GCC говорится, что уровень 1 является наименее точным и может давать много ложных срабатываний, а уровень 3 является наиболее точным ...
Так что здесь происходит? Проблема с моим собственным пониманием или проблема с GCC?
Бонусный вопрос
Я обычно предпочитаю Clang / LLVM GCC для своих проектов, но кажется, что Clang не выдает никаких предупреждений о строгом псевдониме.
Кто-нибудь знает, почему?
Это потому, что он не может обнаруживать нарушения, или потому, что он не соблюдает правила при генерации кода?
l
является постоянным во втором примере. - person Macmade   schedule 19.01.2014union
или приведение кunsinged char*
. - person Jens Gustedt   schedule 19.01.2014