我们如何使用#define语句中工会和结构

问题描述 投票:0回答:3

我要通过微控制器的头文件中,当我发现这个,

 #define DEFA(name, address) __no_init union \
{ \
  struct \
  { \
    volatile unsigned char  name##_L; \
    volatile unsigned char  name##_H; \
  }; \
  struct \
  { \
    volatile unsigned short name##L; \
    volatile unsigned short name##H; \
  }; \
  __ACCESS_20BIT_REG__ name; \
} @ address;

我有多个问题在这里,

  1. 我不知道我们能#define语句中使用union和结构。他们是如何被编译器解释?
  2. 什么是 “名## _ L” 和 “名## L” 的意思。?,尤其是 “##”。
  3. 什么是“__ACCESS_20BIT_REG__名”?
  4. 这是什么新的“@”符号,我用Google搜索,了解这个符号,我觉得没有什么相关的@符号的任何地方,有人说,这不是C标准,这是真的?又是什么意思?

一个人,请给我解释一下这段代码的和平,一切都取决于这片代码,一切都直接或间接地使用这个的#define。 :(

c embedded c-preprocessor preprocessor
3个回答
2
投票
  1. 你可以把最里面的东西宏,它们大多只是文本替换(尽管通过令牌级令牌)。把类型定义和变量声明中宏然而不好的做法,应该尽量避免,除非有没有其他选择。
  2. 它粘贴令牌过去,并创建一个新的预处理器令牌。在这种情况下,它会创建成员变量名。如果你使用DEFA(foo,0)你会得到一个名为foo_Hfoo_L成员。 值得注意的是,这个特殊的宏可能会更好,如果该领域只是命名为H和L为什么会有人想要输入reg.foo_H而非foo.H?使用_LL后缀8位和16位的访问来区分是不是一个非常聪明的主意无论是。
  3. 通过相同的代码中使用的一些自定义类型。为什么他们有一种称为“20位”和32层结构之间的联盟,我不知道。
  4. 非标准扩展。通常它是在一个特定的地址,这是在这里的情况下使用用于可变的分配。也许你有一个内存映射的硬件寄存器,这个宏应该是这样的寄存器的通用声明。

另外值得注意的,工会语法也不是标准C.您需要命名的工会。匿名结构是标准的C,因为C11,但我怀疑这是从一个现代的编译器。

总体而言,非常糟糕的代码。一个非常典型的一种垃圾代码,您在由硅/工具供应商提供微控制器寄存器映射找到。不符合ISO C也不MISRA-C。


1
投票
  1. 我不知道我们能#define语句中使用union和结构。他们是如何被编译器解释?

定义语句只是宏。他们不是由编译器,但由预处理器解释。这是宏内部定义的代码位只是复制粘贴无处不在,在那里你调用/使用宏。如果它包含有效的C / C ++代码,那么它会在下一步编译还,一旦预处理完成。

  1. 什么是 “名## _ L” 和 “名## L” 的意思。?,尤其是 “##”。

是的,我被这##很久也惊讶一次。这是令牌串联。基本上,你可以用它生成“编程”的变量/函数名。因此,例如,你有,

#include <stdio.h> 
#define concat(a, b) a##b 
int main(void) 
{ 
    int foobar = 1; 
    printf("%d", concat(foo, bar)); 
    return 0; 
} 

将打印1,因为它加到foobar在一起,形成foobar

  1. 什么是“__ACCESS_20BIT_REG__ name”?

__ACCESS_20BIT_REG__似乎是在代码中定义可能在其他地方实现定义的宏。该__双下划线跟着一个大写保留实施(使他们可以通过您的uC制造商使用例如)。

  1. 这是什么新的“@”符号,我用Google搜索,了解这个符号,我觉得没有什么相关的@符号的任何地方,有人说,这不是C标准,这是真的?又是什么意思?

这其中有我也难住了。我不认为这是合法的C.

编辑:

其实,关于你的第4点即qazxsw POI符号,我用Google搜索多一些,发现这个qazxsw POI。


0
投票

我想解释这一段代码的最佳方式是通过尝试一个例子:那么从定义@结果?

使用这样定义例如stackoverflow question预处理器产生这些行的代码:

DEFA(name, address)

所以,现在您的问题:

  1. 解释如图所示
  2. 这就是所谓的令牌串联,是concates给定的令牌给宏变量qazxsw POI
  3. ACCESS_20BIT_REG可能被定义在其他地方一个20位长的数据类型的宏
© www.soinside.com 2019 - 2024. All rights reserved.