Почему для этого кода не создается строгие предупреждения строгих псевдонимов?

StackOverflow https://stackoverflow.com/questions/3817474

Вопрос

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

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

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

Это было полезно?

Решение

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

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

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


Обновлять:

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

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

    foo( &myB);

    return 0;
}

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top