简体   繁体   English

可以和void * pointer一起使用吗? 如果没有,怎么办?

[英]Does this work with void *pointers? If not, how?

In our code we have a big struct of mixed types, and want to store a duplicate (const) struct of default values for these. 在我们的代码中,我们有一个很大的混合类型结构,并希望为它们存储一个默认值的重复(const)结构。

When the user want to default a setting, it would be nice to be able to do this by just taking the address offset of the item within the struct, and then assign the value with the same offset in the "defaults" struct, a bit like this: 当用户想要默认设置时,最好能够做到这一点,只需获取该项目在struct中的地址偏移量,然后在“ defaults”结构中为该值分配相同的偏移量即可。像这样:

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

The idea being that if settings->thing points to an int8, the int8 value is copied from defaults, but if settings->other_thing is an int32, the full 32-bits are copied over. 这样的想法是,如果settings-> thing指向int8,则从默认值复制int8值,但是如果settings-> other_thing是int32,则将完整的32位复制过来。

The question is, does this work with void pointers as I've described above? 问题是,如上所述,它是否可以与void指针一起使用? If not, is there a way of doing this? 如果没有,有没有办法做到这一点? Am I missing a better way of achieving this? 我是否错过了实现这一目标的更好方法?

Edit to clarify: We want to set a single value within the struct to the corresponding value within the "defaults" struct. 编辑以澄清:我们想将结构内的单个值设置为“默认”结构内的对应值。

No, this doesn't work. 不,这不起作用。 Pointers of type void * don't have a size associated with them, ie it's unknown what data type they point at. 类型为void *指针没有与之关联的大小,即,未知它们指向的数据类型。 It follows that you can't do the assignment like that, either. 因此,您也无法执行这样的分配。

You should probably just copy from the defaults directly, as suggested in a comment. 如注释中所述,您可能应该直接从默认值复制。

Also note that default is a reserved word in C, so you shouldn't use it for a variable. 另请注意, default是C中的保留字,因此您不应将其用于变量。

If the defaults are globally visible, you might define a macro to hide this: 如果默认值在全局可见,则可以定义一个宏来隐藏它:

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

The user (which I assume is a developer) can now do: 用户(我认为是开发人员)现在可以执行以下操作:

struct settings s;

INITIALIZE(s, thing);

That said, I would (as a developer) prefer something like: 也就是说,我(作为开发人员)更喜欢以下内容:

struct settings s = get_default_settings();

This is more clear, and less magic. 这更清晰,也更神奇。 Sure, it probably takes more time to copy all the fields, but settings are generally not performance-critical. 当然,复制所有字段可能会花费更多时间,但是设置通常对性能并不重要。

Note that the above function might just be: 请注意,上面的功能可能只是:

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

  return the_defaults;
}

Which neatly encapsulates the default values, and removes the global. 它巧妙地封装了默认值,并删除了全局值。

There is no built in type/reflection information for runtime in C. In order to do what you requested, you'd need to know at runtime the actual size of the type you're copying. 在C中,没有针对运行时的内置类型/反射信息。为了执行您所请求的操作,您需要在运行时知道要复制的类型的实际大小。

If you really want to do what you're doing, you need to define your own runtime type information, generally by making each setting a structure of its own.. something like... 如果您确实想做自己在做的事情,则需要定义自己的运行时类型信息,通常是通过使每个设置都有自己的结构来实现的。

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;
};

And then writing a function to copy and return such a value becomes fairly simple. 然后编写一个函数来复制并返回这样的值变得非常简单。

This is quite some overhead if all you want is to copy a few settings, but is pretty much what large configuration systems do. 如果您只想复制一些设置,这将是相当大的开销,但是这几乎是大型配置系统所要做的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM