私は32ビットウィンドウから64ビットへの移植を行っています。アライメントされていないポインタが参照ではないという警告が表示されるのはなぜですか?
void FuncA(double &x)
{
x = 0;
}
void FuncB(double *x)
{
*x = 0;
}
#pack(1)
struct
{
char c;
double x;
} MyStruct;
#pack();
void MyFunc()
{
MyStruct M;
FuncA(M.x); // This is OK
FuncB(&M.x); // This generates a warning C4366
}
充填構造体の次の警告を生成するのメンバーとFuncB
を呼び出す、64ビットを標的VS2010 SP1の下にコンパイル。
警告C4366:単項 '&' 演算子の結果はを呼び出すことはしません
のに対して整列していないかもしれません。私は両方のケースがほぼ同じコードにコンパイルされていると思っていたでしょう。参照が同等のポインタよりも整列の問題から安全かどうか、またはMSVCが単に警告を出していないかどうかプロジェクトでは、構造体のパッキングが維持される必要があり、そう私の選択肢はFuncB
void FuncB(__unaligned double *x)
{
*x = 0;
}
または単純にすべてのそのような場合にを使用する
に変更するかのいずれかです。後者はより移植性が高いので好ましいでしょうが、私はそれがうまくいくと思っています。あるいは、リファレンスケースの警告の欠如は単にコンパイラの欠点です。編集:このエラーのMicrosoftヘルプのエントリはhereです。 __unalignedヘルプは、この警告に従わないと、Itaniumプロセッサで例外がスローされることを示唆しています。 MSDNについてさらに詳しく調べると、there may be issues surrounding unaligned referencesが示唆されます。現在のユーザーには問題はありませんが、将来的にItaniumアーキテクチャーが広く使用されるようになれば、サポートの悪夢を設定する可能性があります。ポインターと__unalignedキーワードを避けるために、パック構造を使用するすべての関数に特定のラッパーを追加するようになりました。
アンアラインドアクセスが整列アクセスより遅い、そしてマルチスレッド環境では、他の望ましくない効果を有することができる(インテルに整列読み出し/書き込みがアトミックであるが、アラインされていないアクセスのためにない場合、その2つのスレッドが値1および2書き込みと^ 31を同じ変数に置き、値を読み取るスレッドが値を揃えた場合は、1または2^31;非アライメントのアクセスであることが保証されます)。他のプラットフォーム(SPARC)では、アラインされていない読み取り/書き込みを処理できず、プロセッサはトラップします。 –
アライメントの悪いアクセスが遅いことを説明するために、「ここではポインタの方が参考になると思うのはなぜか」を更新しました。私はSPARC用のWindowsのバージョンについて認識していないので、その動作は重要ではないと考えています.64ビットARMもまだWindows用には利用できません。 X86とItaniumを残しています... –
C++コンパイラの警告と境界整列されていないアクセスに関するコメントでしたが、sparcの代わりにアルファベットを使用したい場合はアルファ版では複数のWindows OSが動作していますが、新しいバージョンの場合はわかりません。編集について...ああ。答えは以前より良かった! –