g ++的严格别名警告准确性

时间:2018-05-17 16:13:21

标签: c++ gcc language-lawyer strict-aliasing

GCC's documentation-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;
}

然而,当使用-Wstrict-aliasing=1时,g ++仅为它们提供警告。 -Wstrict-aliasing=3 {}未发出警告:https://godbolt.org/g/aox2S1

这些例子实际上是不是违规行为,还是GCC的警告不是违规行为的可靠迹象?

1 个答案:

答案 0 :(得分:3)

严格别名规则以[basic.lval]

非常明确地表达
  

如果程序试图通过以下类型之一以外的glvalue访问对象的存储值,则行为未定义:

     
      
  • 对象的动态类型[...]
  •   

这意味着violate1violate2是相同的,并且必然是违规行为。

一个对象指针can be casted往返于另一个任意对象指针类型,结果是原始指针。在violate3中,如果f_dataint*之前投放到float*的{​​{1}},则*i_data不会发生违规行为,但会在*f_data发生违规行为{1}}