0

私たちのコードには、混合型の大きな構造体があり、これらのデフォルト値の複製(const)構造体を格納したいと考えています。

ユーザーがデフォルト設定を行う場合は、構造体内のアイテムのアドレスオフセットを取得し、「デフォルト」構造体で同じオフセットの値を少し割り当てるだけで、これを実行できると便利です。このような:

void *setting = &settings->thing; // Points to a setting
int offset = setting - &settings;
void *default = &defaults_struct + offset; // Points to the default value
*setting = *default; // Set setting to default value

settings->thingがint8を指している場合、int8値はデフォルトからコピーされますが、settings-> other_thingがint32である場合、完全な32ビットがコピーされます。

問題は、これは私が上で説明したようにvoidポインタで機能するかということです。そうでない場合、これを行う方法はありますか?これを達成するためのより良い方法が欠けていますか?

明確にするために編集:構造体内の単一の値を「デフォルト」構造内の対応する値に設定します。

4

2 に答える 2

6

いいえ、これはうまくいきません。タイプのポインターにはvoid *サイズが関連付けられていません。つまり、それらが指しているデータ型が不明です。したがって、そのような割り当ても実行できません。

コメントで提案されているように、おそらくデフォルトから直接コピーする必要があります。

またdefault、これは C の予約語であるため、変数には使用しないでください。

デフォルトがグローバルに表示されている場合は、これを非表示にするマクロを定義できます。

#define INITIALIZE(s, f) s. f = default_struct. f

ユーザー (私は開発者であると想定しています) は、次のことができるようになりました。

struct settings s;

INITIALIZE(s, thing);

そうは言っても、私は(開発者として)次のようなものを好みます:

struct settings s = get_default_settings();

これはより明確で、マジックが少なくなります。確かに、すべてのフィールドをコピーするにはおそらくもっと時間がかかりますが、設定は通常、パフォーマンスに影響を与えるものではありません。

上記の関数は次のようになることに注意してください。

struct settings get_default_settings(void)
{
  static const struct settings the_defaults = {/* the default values go here*/};

  return the_defaults;
}

デフォルト値をきちんとカプセル化し、グローバルを削除します。

于 2012-09-20T11:11:22.327 に答える
1

C には、実行時の組み込みの型/リフレクション情報はありません。要求したことを実行するには、実行時にコピーする型の実際のサイズを知る必要があります。

本当に自分がしていることをしたい場合は、通常、各設定を独自の構造にすることにより、独自のランタイム型情報を定義する必要があります..何かのような...

struct single_setting {
 int stype;
 union {
  uint8_t s8;
  uint16_t s16;
  uint32_t s32;
  uint64_t s64;
  struct {
   char *s;
   size_t len;
  } sstr;
 } u_value;
};

そして、そのような値をコピーして返す関数を書くことはかなり簡単になります。

いくつかの設定をコピーするだけであれば、これはかなりのオーバーヘッドになりますが、大規模な構成システムが行うこととほとんど同じです。

于 2012-09-20T16:47:45.797 に答える