12

32ビットWindowsから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
}

64 ビットを対象とする VS2010 SP1 でコンパイルする場合FuncB、パックされた構造体のメンバーを使用して呼び出すと、次の警告が生成されます。

警告 C4366: 単項 '&' 演算子の結果は位置合わせされていない可能性があります

一方、呼び出しFuncAはしません。どちらの場合も、ほとんど同じコードにコンパイルされると思っていたでしょう。参照は、同等のポインターよりもアラインメントの問題から何らかの形で安全ですか? それとも、MSVC が本来あるべき場所で警告を出していないだけなのでしょうか? プロジェクトでは構造体のパッキングが維持される必要があるため、私の選択は次のいずれかに変更FuncBすることです

void FuncB(__unaligned double *x)
{
   *x = 0;
}

FuncAまたは、そのようなすべての場合に単に使用します。移植性が高いため、後者の方が望ましいですが、それは機能するのでしょうか、それとも参照ケースで警告がないのは単にコンパイラの欠点なのでしょうか?

編集: このエラーに関する Microsoft ヘルプ エントリはこちらです。__unalignedヘルプは、この警告に注意を払わないと、Itanium プロセッサで例外がスローされることを示唆しています。MSDN をさらに調べてみると、 unaligned references に関連する問題がある可能性があります。これは現在のユーザーにとっては問題にならないかもしれませんが、将来、Itanium アーキテクチャがより広く使用されるようになった場合、サポートの悪夢を設定することになる可能性があります。ポインターと __unaligned キーワードを回避するために、パックされた構造体を使用するすべての関数に特定のラッパーを追加する予定です。

4

1 に答える 1