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 回答