2012-05-12 14 views
7

gcc 4.7(g ++ - mp-4.7(GCC)4.7.0のMacPortsをOS Xで構築)で次のコードをコンパイルすると、一見矛盾した結果になります。厳密なエイリアシングとstd :: arrayとCスタイルの配列

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 

彼らは異なる方法で処理されているのはなぜ?

+0

興味深いことに、私はubuntu 12.04,64ビットでgcc 4.7にエラーを出すことはありません。 – juanchopanza

+0

@juanchopanza '-Wstrict-aliasing = 2'で動作しますか? – StackedCrooked

+0

はい、そうです。警告でもない。 – juanchopanza

答えて

3

std::arrayのアドレスを取得する場合、式arr[0]はなくポインタ演算式(arr + 0)より、リファレンスを返す関数呼び出しarr.operator[](0)と等価です。おそらくコンパイラは、エイリアス警告を生成するときにoperator[]ファンクションコールを「見る」ことを試みません。

関連する問題