这是程序中使用的结构:
struct basic_block { void * aux; /* Many other fields, which are irrelevant. */ };
现在:
我的舞台使用aux
来存储一个struct
,所以每次我想访问某些东西时,我都要做一个强制转换:
( (struct a_long_struct_name *) (bb->aux))->foo_field = foo;
现在,我的问题:每次像这样投下它是一种痛苦,当它是更复杂的表达式的一部分时难以阅读。 我建议的解决方案是:使用宏为我做演员:
#define MY_DATA(bb) ( (struct a_long_struct_name *) (bb)->aux)
然后我可以访问我的数据:
MY_DATA(bb)->foo_field = foo;
但是:我不能将MY_DATA(bb)
本身用作L值(对于malloc
),所以我使用该宏并不是一个好主意:
/* WRONG! I cannot assign to the result of a cast: */ MY_DATA(bb) = malloc (sizeof (struct a_long_struct_name));
我的问题:
我该怎么做才能以干净的方式引用aux
并仍能将其用作L值。
您可以将字段的地址 struct a_long_struct_name **
为struct a_long_struct_name **
,然后取消引用它:
#define MY_DATA(bb) (* ((struct a_long_struct_name **) &(bb)->aux) )
这将适用于您显示的两种结构。
但是,如果可以在声明struct basic_block
的位置知道具体类型的aux
的可能性,那么使用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)
尝试:
#define MY_DATA(bb) ( *(struct a_long_struct_name **) &(bb)->aux)
请注意,这会引入别名,因此您必须在使用宏时保持一致。
没有必要使用宏调用来丢弃代码:
struct a_long_struct_name* strp = malloc(sizeof *strp); if (!strp) bb->aux = strp; strp->foo_field = foo; etc.
你不能。 C禁止通过不同类型的左值表达式( struct a_long_struct_name *
)访问一种类型的对象( void *
struct a_long_struct_name *
),并且违反此规则是一种别名冲突。 从实际角度来看,这意味着允许编译器假设这两个左值不能引用相同的内存,因此可能会以严重破坏代码的方式重新排序读取和写入。 在forms上,它只是未定义的行为,这意味着任何事情都可能发生。
你应该做的是在问题中使用你的代码的原始版本,而忘记使用MY_DATA(bb)
作为左值。 而只是直接分配给bb->aux
。 这就是void *
的用途。
以上就是c/c++开发分享使用(void *)作为通用数据容器时的L值问题相关内容,想了解更多C/C++开发(异常处理)及C/C++游戏开发关注计算机技术网(www.ctvol.com)!)。
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/c-cdevelopment/522971.html