Tag: unions

将结构指针转换为联合指针

我有一个包含各种兼容struct成员的union : enum Type { T1, T2, … }; struct S1 { enum Type type; … }; struct S2 { enum Type type; … }; … union U { enum Type type; struct S1 as_s1; struct S2 as_s2; … }; 这些结构的type字段被视为不可变,并且只访问与当前type对应的union的字段。 我知道只要type不变量得到维护,就会定义将union U *为struct S1 * ,但反过来也是如此吗? struct S1 *s1 = malloc (sizeof (struct S1)); […]

如何将Visual Studio中的结构打包到包含uint32_t的24位?

我试图将现有的应用程序从32位ARM微控制器移植到桌面平台,如Microsoft Windows。 GCC用在ARM上,我能够使用32位MinGW编译器在Windows上成功编译应用程序,但是我没有成功使用Microsoft的Visual Studio编译器,这就是我在这里寻求帮助的原因。 这是我的应用程序正在做的事情: 我有一些帧缓冲区,每个像素包含三个字节,所以我的内存看起来像RGBRGBRGB等等。 我在ARM上使用DMA通道将像素推出到显示器,我的显示器直接理解这种内存布局。 我还想节省一些CPU周期,所以我想使用ARM的饱和ADD __UQADD8来绘制我的帧缓冲区,使用单个操作在所有三个通道上执行饱和加法。 为此,我需要在一个整数中使用所有三个通道作为__UQADD8参数。 这就是我为帧缓冲区的一个像素使用联合的原因是通过提供一个包含R,G,B作为uint8_t的结构并提供与24位宽整数标记数据相同的内存来访问单独的通道: union Rgb { struct { uint8_t r; uint8_t g; uint8_t b; } ch; unsigned int data : 24 __attribute__((__packed__)); } 将24位宽度和打包属性添加到数据整数中,以将整数的宽度限制为三个字节。 然后我可以像这样使用像素中的数据: Rgb Rgb::operator+(const Rgb & op) { __UQADD8(data, op.data); return Rgb(data); } 请注意, __UQADD8神奇地只写入我的整数的四个字节中的三个,并且不会改变我的帧缓冲区中下一个RGB的R通道。 以下测试程序certificate我的RGB在使用GCC时都紧凑: #include #include union Rgb { struct { uint8_t […]

这个位域会以我期望的方式工作吗?

我一直在读C中的位域,C标准如何不强制机器字中字段的任何特定顺序,等等。 我希望这个问题适合SO的格式。 我的问题是我的结构(后面的定义)是否会以我期望的方式实际执行。 这是我想出的定义,然后我会讨论我想要的东西: typedef enum { STATE_ONE, STATE_TWO, STATE_THREE, STATE_FOUR } __attribute__ ((packed)) State; typedef struct MyStruct { // One of State enum (maximum of 4 states). unsigned state : 2; // Remaining 30 bits are used differently depending on ‘state’. union { // If ‘state’ is STATE_ONE (0), the remaining bits are an […]

C中“union”和“struct”之间的主要区别是什么?

可能重复: C中结构与联盟的区别 我能理解结构意味着什么。 但是,我对union和struct之间的区别感到困惑。 联盟就像是记忆的一部分。 究竟是什么意思。

为什么普通变量不允许使用位域?

我想知道为什么位域与联合/结构一起使用但不能使用像int或short这样的正常变量。 这有效: struct foo { int bar : 10; }; 但这失败了: int bar : 10; // “Expected ‘;’ at end of declaration” 为什么此function仅在联合/结构中可用而不在变量中? 技术不一样吗? 编辑: 如果允许,你可以创建一个3字节的变量,而不是每次都使用struct / union成员。 这就是我对结构的看法: struct int24_t { int x : 24 __attribute__((packed)); }; struct int24_t var; // sizeof(var) is now 3 // access the value would be easier: var.x = […]

具有“共同初始序列”的联合’双关语’结构:为什么C(99+)而不是C ++规定了’联合类型的可见声明’?

背景 关于通过union进行类型惩罚的大多数未实现或实现定义的性质的讨论通常引用以下位,在此通过@ecatmur( https://stackoverflow.com/a/31557852/2757035 ),对标准的豁免-layout struct具有成员类型的“公共初始序列”: C11( 6.5.2.3结构和联合成员 ; 语义 ): […]如果一个union包含几个共享一个公共初始序列的结构(见下文),并且如果union对象当前包含这些结构中的一个,则允许检查它们中任何一个的公共初始部分。 可以看到已完成的工会类型的声明 。 如果对应的成员具有一个或多个初始成员的序列的兼容类型(并且对于位字段,具有相同的宽度),则两个结构共享共同的初始序列 。 C ++ 03( [class.mem] / 16 ): 如果POD-union包含两个或多个共享公共初始序列的POD结构,并且如果POD-union对象当前包含这些POD结构中的一个,则允许检查它们中的任何一个的公共初始部分。 如果对应的成员具有一个或多个初始成员的序列的布局兼容类型(并且对于位字段,具有相同的宽度),则两个POD结构共享共同的初始序列。 这两个标准的其他版本都有类似的语言; 从C ++ 11开始,使用的术语是标准布局而不是POD 。 由于不需要重新解释,这不是真正的类型惩罚,只是应用于union成员访问的名称替换。 针对C ++ 17(臭名昭着的P0137R1)的提议使得这种显式使用的语言就像“访问就像其他结构成员被提名一样”。 但请注意粗体 – “ 在任何地方都可以看到完整类型的联合声明 ” – C11中存在的条款,但在2003年,2011年或2014年的C ++草案中没有任何内容(几乎完全相同,但后来的版本取代了“ POD“使用新术语标准布局 )。 在任何情况下,在任何C ++标准的相应部分中都完全没有’ union类型位的可见声明。 @loop和@ Mints97,在这里 – https://stackoverflow.com/a/28528989/2757035 – 显示这一行在C89中也没有,首先出现在C99中,然后保留在C中(尽管如此,再一次,永远不会过滤到C ++)。 关于此的标准讨论 [剪断 […]

uint32_t和uint8_t的联合未定义的行为?

在这个答案的评论中,据说使用如下的联合将整数分割成它们的字节将是未定义的行为。 在那个地方给出的代码是相似的,虽然与此不相同,如果我更改了代码的未定义行为相关方面,请注意。 union addr { uint8_t addr8[4]; uint32_t addr32; }; 到目前为止,我认为这将是一个很好的方法来做像addr = {127, 0, 0, 1}; 并得到相应的uint32_t作为回报。 (我承认根据我的系统的字节顺序,这可能产生不同的结果。但问题仍然存在。) 这是未定义的行为吗? 如果是这样,为什么? (我不知道C ++中的UB是什么意思是访问非活动的联盟成员。 ) C99 在这一点上,C99显然非常接近C ++ 03。 C ++ 03 在联合中,最多一个数据成员可以在任何时间处于活动状态,也就是说,最多一个数据成员的值可以随时存储在并集中。 C ++ 03,第9.5(1)节,第162页 然而 如果POD-union包含几个共享一个共同初始序列的POD结构,则允许检查任何POD结构成员的公共初始序列同上。 如果两个POD-struct类型具有相同数量的非静态数据成员,则它们是布局兼容的,并且相应的非静态数据成员(按顺序)具有布局兼容类型 C ++ 03,第9.2(14)节,第157页 如果两种类型T1和T2是相同类型,则T1和T2是布局兼容类型。 C ++ 03,第3.9(11)节,第53页 结论 因为uint8_t[4]和uint32_t不是同一类型(我猜,一个严格的别名 )(加上两个都不是POD结构/联合)上面的确是UB? C ++ 11 请注意,聚合类型不包含联合类型,因为具有联合类型的对象一次只能包含一个成员。 C ++ 11,脚注46,第42页

关于C – union中的union作为一种类型并且作为另一种类型读取的问题 – 是否已实现定义?

我正在阅读K&R中关于C的联合,据我所知,联合中的单个变量可以包含几种类型中的任何一种,如果某些东西存储为一种类型并且提取为另一种类型,则结果纯粹是实现定义的。 现在请检查以下代码段: #include int main(void) { union a { int i; char ch[2]; }; union au; u.ch[0] = 3; u.ch[1] = 2; printf(“%d %d %d\n”, u.ch[0], u.ch[1], ui); return 0; } 输出: 3 2 515 在这里,我在u.ch分配值,但是从u.ch和ui检索。 它是实现定义的吗? 或者我做的事情真的很傻? 我知道这对其他大多数人来说似乎很初学,但我无法弄清楚输出背后的原因。 谢谢。