"#define something something" in C

3

我正在查看一些微控制器的C头文件,其中有如下代码:

#define OSCCONL OSCCONL
extern volatile uint8_t OSCCONL __attribute__((__sfr__));
#define OSCCONH OSCCONH
extern volatile uint8_t OSCCONH __attribute__((__sfr__));
#define CLKDIV CLKDIV
extern volatile uint16_t CLKDIV __attribute__((__sfr__));
__extension__ typedef struct tagCLKDIVBITS {...}

那些重复的"#define A A"有什么作用?
2个回答

4
作为预处理器不知道C语言和变量,因此需要添加一些定义来确定变量(variable)是否在C代码中被定义。您可以在代码后面使用这些定义。
示例:
#if defined(OSCONL)
OSCONL = something;
#endif

如果你的微控制器没有这个寄存器,那么代码的这一部分将无法编译。这是一种非常常见的技术。
编辑: > 但是如果只有 #define OSCCONL 不是也能起到同样的作用吗?
这个想法是让 #define 和变量或函数名相同。这使得代码一致且易于记忆。
否则,你将不得不有不同的 #define 和对象名称,使编码更加困难,因为你必须记住两者。在这种约定下,你可以阅读微控制器的文档,并使用相同的名称来检查此对象是否存在,而无需记住 #define 的名称。

1
但是如果只有#define OSCCONL,那么它不会起到同样的作用吗?问题是为什么OSCCONL出现了两次。 - edtheprogrammerguy
OSCCONL似乎是一个特定于编译器的属性。用OSCCONL定义它并给出定义值OSCCONL可能是一种方便的做法,因为如果需要更改定义而不更改定义,则更改定义值OSCCONL将更容易。 - Raildex
1
我建议添加解释,即#define OSCCONL OSCCONL将替换变量声明extern volatile uint8_t OSCCONL __attribute__((__sfr__))中的OSCCONLOSCCONL。提出的替代方案#define OSCCONL将用空字符串替换OSCCONL,导致语法错误extern volatile uint8_t __attribute__((__sfr__)) - Bodo

3

其中一个用途可能是在宏检查中使用,例如#ifdef或#ifndef。

这样可以进行条件编译,只有部分源代码将被编译到二进制文件中。


2
但是如果只有#define OSCCONL,它不会起到同样的作用吗?问题是为什么OSCCONL出现了两次。 - edtheprogrammerguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接