いくつかのフィールドを持つレコードを格納するCライブラリがあります。スキーマは、レコード内の各フィールドのタイプを含め、テキストファイルから読み込まれます。
質問の目的で単純化するために、私が持っていると想像してください
typedef enum my_type_enum
{
INT32, //32-bit integer
MYSTRUCT, //some struct I have, details irrelevant
...
} my_type_enum;
typedef struct my_var
{
my_type_enum typetag;
unsigned char* data;
} my_var;
my_var myrecord[numfields];
スキーマファイルは、myrecordの各フィールドがint32_tまたはmystructのどちらを保持する必要があるかを示します。私のライブラリはスキーマファイルを読み取り、myrecordのmy_varごとにタグを設定し、データに適切な量のスペースを割り当てます。
my_varは不透明で、クライアントプログラムは基本的に単純なデータに使用します
void set(my_var* record, size_t field, void * src)
{
memcpy(record[field].data, src, datatypes[record[field].typetag].size);
}
int32_t x = 5;
set(myrecord, 0, &x);
レコードに値を格納し、同様のget()を使用して物事を取り出します。
タグ付きのmy_var型を使用すると、データがmy_var内にあると型チェックが可能になりますが、スキーマにレコードが3つのINT32を保持していると示されている場合は、データをset()しようとしているときに、srcがmystructではなくint32_tを指していることを確認する必要はありません。そのmy_varに。
明らかに、int32_t*またはmystruct*がvoid*に変換される前に、set()をラップする何かでチェックを実行する必要があります。typeof()のトリックを使用したコンパイル時のチェックを見てきました。私が望むことはおそらく不可能だと思いますが、あなたはすべてのトリックを知っていることは決してありません...
クライアントプログラムのコンパイル時にスキーマを読み取り、mystructを保持するようにタグ付けされたmy_varにint32_tをコピーしようとするとコンパイラエラーが発生するset_CHECKED()ラッパーマクロを生成する機能を提供するよりも良い方法はありますか?GCC拡張機能は問題ありません。