2012-02-24 7 views
3

最適化レベルが-o0の場合、次の2つのコードが正常に動作します。 しかし、最適化レベルが-o0以外の場合、最初のコードはある時点でクラッシュしますが、秒はクラッシュしません。理由を説明していただけますか?iOSの-o0以外の最適化レベルでクラッシュする

unsigned char* _pos = ...; 

double result; 

*((int*)&result) = *((int*)_pos; 
unsigned char* _pos = ...; 
double result; 

int* curPos = (int*)_pos; 
int* resultPos = (int*)&result; 
*resultPos = *curPos; 

EDIT: ところで、このコードは、インライン関数です。関数がインライン化されていない場合、最適化を行ってもクラッシュは発生しません。

+0

デバッガを使用せずに自分自身を見つけてみませんか? :-) –

+0

私は何もしませんでした - –

+3

1と2の両方が厳密なエイリアシング規則を破りました。コンパイラは、クラッシュするコードを生成し、生成し、そのオプションでクラッシュしないコードを生成します。それについてはそれほど多くのことは言いません。 http://stackoverflow.com/questions/98650/what-is-the-strict-aliasing-rule –

答えて

4

ここのコードは実際には一度にいくつかの問題を生じます。 最初に、前述のように、コードはエイリアシング規則に違反しているため、結果は標準ごとに定義されていません。厳密に言えば、コンパイラは最適化中にたくさんのものを実行できます(これは、上記のコードがインライン展開されたときの実際のケースです)。

2番目(これは実際の問題です) - char *をint *にキャストすると、は、ポインタのアライメントを想定してになります。プラットフォームABIによると、charは1バイトに整列できますが、int - 少なくとも4(倍精度は8バイト整列、btw)です。システムは、整列していない負荷に耐えることができるが、常にそうとは限らない。 arm/darwinでは、4バイトのアラインメントされていないロードは許容できますが、8では許されません。後者の場合は、コンパイラが2つの連続したロード/ストアドを1にマージすることを決定するときに起こります。このような8バイトの負荷を生成する。

あなたのコードを短く修正してください:)この特定のケースでは、memcpy/memmoveが役に立ちます。

+0

私はmemcpyを試しています。トリックをしてください。大きな説明ありがとう:) –

+0

優秀な説明。名声 – braden

関連する問題