C全局匿名结构/联合

pus*_*ect 0 c embedded struct arm anonymous

我有一个uint64变量,通常只需要高或低32位访问.我使用的是32位ARM Cortex M0,为了提高速度,我试图将uint64变量与C中的两个uint32变量重叠,使用匿名结构,希望避免指针算法访问成员.

我正在尝试做什么?可能是使用命名联合同样快,但现在我只是感兴趣,如果它可以没有.以下内容无法成功编译:

http://goo.gl/ejx37y

#include <stdint.h>

volatile union {
  uint64_t ab;
  struct { uint32_t a, b; };
};

int main(void)
{
  a = 1;
};
Run Code Online (Sandbox Code Playgroud)

dav*_*mac 6

您定义没有实例的联合,这意味着没有包含成员的联合对象.你可能会做这样的事情:

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)

如果您确实使用#defines,请小心它们会影响标识符(a,b,ab)的任何声明/使用,即使是那些不同范围的标识符.我建议,而不是你刚刚通过显式访问值u对象(如u.a,u.b,u.ab).

我已从volatile声明中删除,因为我非常怀疑你真的需要它.但如果你愿意,你当然可以把它添加回来.

(注意:这个问题最初的代码分为两个文件,main.h和main.c.我的答案相应地有两个文件的代码.但是,这些可以很容易地组合成一个).


Som*_*ude 5

根本不可能这样做.全局变量(就像您在头文件中声明的那样)与匿名结构或联合的成员不同,它根本不起作用.

并且具有匿名结构或联合将无助于指针算法,该结构仍将位于内存中的某处,并且编译器使用结构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)