Почему для этого кода не генерируются строгие предупреждения о псевдонимах? - PullRequest
4 голосов
/ 29 сентября 2010

У меня есть следующий код:

struct A
{
    short b;
};

struct B
{
    double a;
};


void foo (struct B* src)
{
    struct B* b = src;
    struct A* a = (struct A*)src;

    b->a = sin(rand());

    if(a->b == rand())
    {
        printf("Where are you strict aliasing warnings?\n");
    }
}

Я компилирую код с помощью следующей командной строки:

gcc -c -std=c99 -Wstrict-aliasing=2 -Wall -fstrict-aliasing -O3 foo.c

Я использую GCC 4.5.0.Я ожидал, что компилятор выведет предупреждение:

 warning: dereferencing type-punned pointer will break strict-aliasing rules

Но это никогда не так.Я могу распечатать предупреждение для других случаев, но мне интересно, почему, в данном случае, это не так.Разве это не очевидный пример нарушения строгих правил наложения имен?

1 Ответ

1 голос
/ 29 сентября 2010

Документы GCC для -Wstrict-aliasing=2 говорят (выделено мое):

Уровень 2: Агрессивный, быстрый, не слишком точный.Может по-прежнему иметь много ложных срабатываний (хотя и не так много, как на уровне 1), и мало ложных срабатываний (но, возможно, больше, чем на уровне 1) .В отличие от уровня 1, он только предупреждает, когда адрес взят.Предупреждает о неполных типах.Запускается только во внешнем интерфейсе.

Кажется, ваш код не слишком сложен, поэтому я не уверен, почему может быть ложный минус, но, возможно, это потому, что вы не используетеоператор & address-of для выполнения псевдонимов (это может означать то, что подразумевается под «только предупреждает, когда адрес взят»)


Обновление:

Это неиспользуя адрес оператора.Если я добавлю следующий код в файл foo.c:

int usefoo(void)
{
    struct B myB = {0};

    foo( &myB);

    return 0;
}

Предупреждение выдается.

Если usefoo() находится в отдельном модуле компиляции, предупреждение не выдается.

...