严格别名规则和std :: array与C风格数组的比较

8

当使用gcc 4.7(在OS X上使用MacPorts构建的g ++ -mp-4.7(GCC)4.7.0)编译以下代码时,我得到了看似矛盾的结果。

当我尝试将std :: array的一部分重新解释和解引用为uint32_t时,编译器不会发出警告,但是使用C样式数组时会发出警告。

示例代码:

#include <array>
#include <cstdint>

int main() {    
    std::array<uint8_t, 6> stdarr;
    *reinterpret_cast<uint32_t*>(&stdarr[0]) = 0; // OK

    uint8_t arr[6];
    *reinterpret_cast<uint32_t*>(&arr[0]) = 0;
    // ^ error: dereferencing type-punned pointer will break strict-aliasing rules [-Werror=strict-aliasing]
}

编译器命令是:
$ g++ -o test -std=c++0x -Wall -Wextra -Werror main.cpp

为什么它们被区别对待?

有趣的是,在Ubuntu 12.04,64位上的gcc 4.7上,我没有收到任何错误。 - juanchopanza
@juanchopanza 它能与“-Wstrict-aliasing=2”一起使用吗? - StackedCrooked
是的,它确实可以。甚至没有警告。 - juanchopanza
1个回答

4

当获取std::array的地址时,表达式arr[0]等同于函数调用arr.operator[](0),它返回一个引用,而不是指针算术表达式(arr + 0)。也许编译器在生成别名警告时不会尝试“看穿”operator[]函数调用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接