使用(无效*)时,作为一个通用的数据容器L值的麻烦 [英] L-value trouble when using a (void *) as a generic data container

查看:105
本文介绍了使用(无效*)时,作为一个通用的数据容器L值的麻烦的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

下面是在程序中使用的结构:

Here is a structure used in a program:

struct basic_block
{
  void * aux;

  /* Many other fields,
  which are irrelevant.  */
};

现在


  1. basic_block 的几个实例程序的执行过程中存在。

  2. 该项目工程分阶段/通行证,这是一个接一个执行。

  3. 辅助字段是为存储级和 basic_block A阶段的执行过程中的具体数据,并释放通过舞台本身(所以下一个阶段可以重复使用它)。这就是为什么它是一个无效*

  1. Several instances of basic_block exist during the execution of the program.
  2. The program works in stages/passes, which are executed one after another.
  3. The aux field is meant for storing stage and basic_block specific data during the execution of a stage, and freed by the stage itself (so the next stage can reuse it). This is why it is a void *.

我的舞台使用辅助来存储结构,所以我想访问的东西每一次,我一定要做投:

My stage uses aux to store a struct, so each time I want to access something, I have to do a cast:

( (struct a_long_struct_name *) (bb->aux))->foo_field = foo;

现在,我的问题:这样每次铸造这是一个痛苦,难以阅读时,它是更为复杂的前pressions的一部分。我提出的解决办法是:使用宏做演员对我来说:

Now, my problem: Casting it each time like this is a pain, and difficult to read when it is part of more complicated expressions. My proposed solution was: Use a macro to do the cast for me:

#define MY_DATA(bb) \
  ( (struct a_long_struct_name *) (bb)->aux)

然后我可以访问我的数据:

Then I can access my data with:

MY_DATA(bb)->foo_field = foo;

但我不能用 MY_DATA(BB)本身的作为L值(一个的malloc ),所以我使用的宏是不是一个好主意毕竟:

But: I cannot use MY_DATA(bb) itself as an L-value (for a malloc), so I using that macro isn't such a good idea after all:

/* WRONG! I cannot assign to the result of a cast:  */
MY_DATA(bb) = malloc (sizeof (struct a_long_struct_name));

我的问题:

我可以以参考做辅助在一个干净的方式,仍然可以使用它作为一个L值。

What can I do in order to refer to aux in a clean way and still be able to use it as an L-value.

推荐答案

您可以施放的地址的领域,以结构a_long_struct_name ** 然后取消对它的引用:

You can cast the address of the field to struct a_long_struct_name ** and then dereference it:

#define MY_DATA(bb) \
   (* ((struct a_long_struct_name **) &(bb)->aux) )

这将在这两个你都呈现构建工作。

This will work in both the constructs you have shown.

如果设定的可能性的具体类型的辅助可在该点被称为其中,结构basic_block 是宣布,不过,这将是更清洁的使用工会:

If the set of possibilities for the concrete type of aux can be known at the point where struct basic_block is declared, though, it would be cleaner to use a union:

struct basic_block
{
  union {
      struct a_long_struct_name *alsn;
      /* etc */
  } aux;

  /* Many other fields,
     which are irrelevant.  */
};

然后

#define MY_DATA(bb) ((bb)->aux.alsn)

这篇关于使用(无效*)时,作为一个通用的数据容器L值的麻烦的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆