точность предупреждений о строгом псевдониме в g ++ - PullRequest
0 голосов
/ 17 мая 2018

В документации GCC говорится, что -Wstrict-aliasing=3 является наиболее точным уровнем и что более низкие уровни с большей вероятностью дают ложные срабатывания.

Я полагаю, что все следующие примеры нарушают правило строгого алиасинга:

float violate1(float a_float)
{
    float * f_data(&a_float);
    int * i_data((int *)f_data);
    int value(*i_data);
    return value + a_float;
}

float violate2(float a_float)
{
    int * i_data((int *)&a_float);
    int value(*i_data);
    return value + a_float;
}

float violate3(float *f_data)
{
    int * i_data((int *)f_data);
    int value(*i_data);
    return value + *f_data;
}

Тем не менее, g ++ выдает предупреждения для всех, только когда используется -Wstrict-aliasing=1. С -Wstrict-aliasing=3 предупреждения не выдаются: https://godbolt.org/g/aox2S1

Действительно ли примеры не являются нарушениями или же предупреждения GCC не являются достоверным признаком нарушений?

1 Ответ

0 голосов
/ 18 мая 2018

Правило строгого псевдонима сформулировано в очень ясных терминах из [basic.lval]

Если программа пытается получить доступ к сохраненному значению объекта через glvalueкроме одного из следующих типов поведение не определено:

  • динамический тип объекта [...]

Это будет означать violate1 и violate2 - это одно и то же и обязательно является нарушением.

Указатель объекта может быть приведен к другому произвольному типу указателя объекта, результатом является исходный указатель.В violate3, если f_data является int*, ранее приведенным к float*, не будет нарушения с *i_data, но тогда это будет нарушение на *f_data

...