将变量转换为结构定义中定义的并集类型

时间:2019-03-19 13:15:51

标签: c struct casting union typedef

实际上,我在用C语言将一个无符号的int变量转换为在结构类型的声明中声明的并集类型时遇到一些困难。

我需要以与编写结构中定义的并集字段相同的方式设置变量。

包含的头文件中的声明:

typedef struct {
    [...]

    union {
        unsigned long COMPLETE_VALUE;
        struct {
            unsigned long   UPPER:16;           /* [15:0] */
            unsigned long   LOWER:16;           /* [31:16] */
        } SUB_STRUCT;
    } UNION;

    [...]
} STRUCT_TYPE;

c源文件中的变量:

STRUCT_TYPE *pStructure;                        /* the reference structure */
unsigned long dummyVar;                         /* dummy variable */

/* writing the upper field in the structure */
pStructure->UNION.SUB_STRUCT.UPPER = some_value;

问题: 是否可以使用结构类型STRUCT_TYPE?的内部并集类型来修改“ dummyVar”的值? 是否可以将变量强制转换为结构内定义的并并访问子结构的字段?

如果可以像下面显示的那样或以类似的方式修改变量,这将非常有用:

((<CAST>) dummyVar).UNION.SUB_STRUCT.UPPER = some_value;

注意: -STRUCT_TYPE的声明不能更改。 -无法写入或编辑结构pStructure。 -pStructure的访问行为需要复制到dummyVar。

反正这在C语言中有可能吗?

提前谢谢!

马丁

2 个答案:

答案 0 :(得分:1)

  

是否可以使用结构类型STRUCT_TYPE的内部并集类型来修改“ dummyVar”的值?

可能没有,因为您有这个:

typedef struct {
    [...]

    union {

我假设[...]意味着那里有结构成员。

  

是否可以将变量强制转换为结构内定义的联合并访问子结构的字段?

不是,除非它是该结构的初始部分,即使如此,它还是有问题的。将联合作为一个不紧密耦合到该结构的单独的typedef可能会更聪明。

此外,并集使用的位域不是标准化的,您不知道它们是如何最终移植到内存中的。

在这里要做的聪明的事情可能是忘记所有有关该结构的信息,而只是做

uint32_t u32 = ...
uint16_t ms = u32 >> 16;
uint16_t ls = u32 & 0xFFFFu;

此代码可移植,无论位域实现和字节顺序如何。

答案 1 :(得分:1)

  

可以使用内部变量修改“ dummyVar”的值   结构类型STRUCT_TYPE的并集类型?

尽管考虑了大小和表示形式,但不能,在示例中将任何内容强制转换为内部并集类型,因为类型转换仅适用于标量类型。有些游戏可以玩指针和易碎的代码重复,但是我强烈建议不要使用这种恶作剧,因此我拒绝举一个例子。

但是,如果要为dummyVarSTRUCT_TYPE.UNION.COMPLETE_VALUE的某些特定值将UPPER的值设置为与LOWER对应的值,则在C99和更高版本中您可以通过复合文字来实现:

dummyVar = ((STRUCT_TYPE) { .UNION = { .SUB_STRUCT = { some_upper, some_lower } } }).UNION.COMPLETE_VALUE;

请注意,尽管(STRUCT_TYPE)类似于强制转换,但它只是复合文字的语法的一部分。强制转换为结构类型不能超过强制转换为联合类型。

或者,在未定义STRUCT_TYPE的翻译单元中,您可以为内部联合类型写一个复合文字,但这会更糟。由于该类型没有标签或别名,因此该类型的复合文字将需要重现其完整定义。这种复合文字的类型在技术上与任何定义了两者的翻译单元中的结构成员的类型都不兼容,但实际上,我没有任何理由怀疑您会为{获得相同的值{1}}。