pus*_*ect 0 c embedded struct arm anonymous
我有一个uint64变量,通常只需要高或低32位访问.我使用的是32位ARM Cortex M0,为了提高速度,我试图将uint64变量与C中的两个uint32变量重叠,使用匿名结构,希望避免指针算法访问成员.
我正在尝试做什么?可能是使用命名联合同样快,但现在我只是感兴趣,如果它可以没有.以下内容无法成功编译:
#include <stdint.h>
volatile union {
uint64_t ab;
struct { uint32_t a, b; };
};
int main(void)
{
a = 1;
};
Run Code Online (Sandbox Code Playgroud)
您定义没有实例的联合,这意味着没有包含成员的联合对象.你可能会做这样的事情:
main.h:
typedef union {
uint64_t ab;
struct { uint32_t a, b; };
} u_t;
extern u_t u;
Run Code Online (Sandbox Code Playgroud)
main.c中:
u_t u = { .a = 1; };
Run Code Online (Sandbox Code Playgroud)
如果你真的想(在main.h中):
#define a u.a
#define b u.b
#define ab u.ab
Run Code Online (Sandbox Code Playgroud)
如果您确实使用#define
s,请小心它们会影响标识符(a,b,ab)的任何声明/使用,即使是那些不同范围的标识符.我建议,而不是你刚刚通过显式访问值u
对象(如u.a
,u.b
,u.ab
).
我已从volatile
声明中删除,因为我非常怀疑你真的需要它.但如果你愿意,你当然可以把它添加回来.
(注意:这个问题最初的代码分为两个文件,main.h和main.c.我的答案相应地有两个文件的代码.但是,这些可以很容易地组合成一个).
根本不可能这样做.全局变量(就像您在头文件中声明的那样)与匿名结构或联合的成员不同,它根本不起作用.
并且具有匿名结构或联合将无助于指针算法,该结构仍将位于内存中的某处,并且编译器使用结构base-address中的偏移来找出成员的位置.但是,由于在编译时都知道基址和成员偏移,因此编译器通常能够生成代码以直接访问成员,就像任何其他变量一样.如果您不确定,请查看生成的代码.
因此,跳过具有匿名结构的废话,在头文件中正确定义它们,并在头文件中声明这些结构的变量,同时在某些源文件中定义这些变量.
所以对于头文件:
union you_union
{
uint64_t ab;
struct { uint32_t a, b; };
};
extern union your_union your_union;
Run Code Online (Sandbox Code Playgroud)
并在源文件中
union your_union your_union;
Run Code Online (Sandbox Code Playgroud)