私はUnitTest++フレームワークを使用して、担当するCコードに単体テストを実装しています。最終製品は埋め込まれ、const構造を使用して構成情報を保持します。ターゲットホストは非同期で構成を変更できるため、構造体のメンバーはすべて揮発性です。一部の構造も揮発性として宣言されています。
const_castを使用して、UnitTest Windows 7ホストでvolatileキーワードがない構造インスタンスを変更しようとすると、セグメンテーション違反が発生します。これは私には理にかなっています。ただし、構造体インスタンスがvolatileキーワードで宣言されている場合、テストは合格です。これは私には意味がありません。
これは、Win7でのgccの問題を示す簡単なコード例です。定義値を切り替えると、構造体の揮発性インスタンスが使用されているかどうかに応じて、segfaultが表示されるかどうかが決まります。
typedef struct
{
volatile int foo;
volatile int bar;
} TestStruct;
const TestStruct constStruct = { 1, 2};
volatile const TestStruct volatileConstStruct = { 3, 4};
#define SEG_FAULT 0
int main(void)
{
TestStruct * constPtr = const_cast<TestStruct*>(&constStruct);
TestStruct * constVolPtr = const_cast<TestStruct*>(&volatileConstStruct);
#if(SEG_FAULT == 0)
constVolPtr->foo = 10;
#else
constPtr->foo = 20;
#endif
}
volatileキーワードがセグメンテーション違反の回避策を提示する理由を誰かが理解するのを手伝ってもらえますか?また、すべての構造インスタンスにvolatileキーワードを追加せずに、単体テスト用に構造内の値を変更できるようにする方法を誰かが提案できますか?
編集:
私はあなたがCでこれを行うことができることをちょうど発見しました:
#define const
上記の効果的な「constundefine」をテストフィクスチャに含めると、ターゲットコンパイラがconstキーワードを認識し、構造をフラッシュメモリに正しく配置できるようになります。ただし、UnitTest ++コンパイラのプリプロセッサはconstキーワードを削除するため、テストフィクスチャは構造体を変更できます。
このソリューションの欠点は、関数呼び出しの正しいconst操作を検証する単体テストを追加できないことです。ただし、構造体インスタンスからconstを削除することはできません(データをフラッシュに配置する必要があります)ので、これは私が耐えなければならない欠点のようです。