6

unsigned long *を受け取る関数があり、unsigned int *を受け取る外部ライブラリに渡す必要があります。このプラットフォームでは、unsigned int/longは同じサイズです。

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibAtomicUpdateVar((unsigned int*)var); // lib atomically updates variable
}

これにより、厳密なエイリアシングルールに違反しているという警告が生成されます。回避策はありますか?

ありがとうございました

編集:明確ではないことをお詫び申し上げます。コードはアトミックアップデートであるため、ライブラリを回って保存することはできません。アセンブリにドロップダウンすることもできますが、C++でこれを実行したいと思います。

4

3 に答える 3

8
void UpdateVar(unsigned long* var) {
   unsigned int x = static_cast<unsigned int>(*var);
   ExternalLibUpdateVar(&x);
   *var = static_cast<unsigned long>(x);
}
于 2010-09-21T19:44:14.280 に答える
2

これは機能するはずです:

void UpdateVar(unsigned long* var) {
   // this function will change the value at the address of var
   ExternalLibUpdateVar(reinterpret_cast<unsigned int*>(var));
}
于 2010-09-21T19:43:40.497 に答える
1

C規格には、同じサイズである必要があることintを義務付けているものはありません。longさらに、それらが同じサイズであっても、標準では同じ表現を要求するものはありません(特に、2つのタイプ間のエイリアシングが機能しないように、パディングビットとトラップ表現の互換性のない組み合わせを持つ可能性があります有用な目的)。

規格の作成者は、エイリアシングがそのようなエイリアシングを認識する目的を果たさないintプラットフォームをターゲットとする実装者を強制することを望んでいませんでした。long彼らはまた、一部のプラットフォーム(エイリアシングが目的を果たすもの)に適用できるルールを書きたくありませんでしたが、他のプラットフォーム(そうでないもの)には適用できませんでした。代わりに、彼らは、高品質のコンパイラを書いている人々は、それが有用である場合にエイリアシングを認識しようとするだろうと考えました。

ある32ビットタイプへのポインタを使用して、同じ表現を持つ別の32ビットタイプの値を読み書きできることは、特にAPIがどのタイプを期待するかに関して分割されている場合に、明らかに役立ちます。プラットフォーム上の一部の一般的なAPIがint*32ビット値を使用しlong*、他のAPIがを使用する場合、そのプラットフォームの高品質の汎用実装では、一方のタイプのデータに他方のポインターを使用してアクセスできるようにする必要があります。

ただし、残念ながら、一部のコンパイラの作成者は、プログラムのより大きなサブセットを有効に処理するよりも、プログラムの特定のサブセットを迅速に処理することに関心があり、を使用するAPI間でデータを交換する必要がある場合、有用なコードの生成に依存することはできません。エイリアス解析を完全に無効にしない限り、データ表現は同じですが、名前付きタイプが異なります。もちろん、マイクロコントローラでの汎用使用に適したCの方言を対象としている場合、そのような問題は問題ではありません。

于 2016-08-19T20:19:49.143 に答える