C - #define宏

时间:2017-04-18 00:19:33

标签: c

我已经做了一些搜索并咨询了我的一个朋友,但也希望得到StackExchange的社区输入。前言我主要是一个被抨击低级别固件版本的HW人员,请原谅我任何看似常识的东西。我过去做过C编程,但已经有一段时间了。

对于定制ASIC,我不同的是我们有许多控制/状态寄存器,我们将通过软件/固件访问(我可能从现在开始称之为SW)。对于我们的verilog / SV / UVM测试平台,我们有一个脚本可以构建一个verilog头文件`define file。在这种情况下,我们有以下结构:

`define REG_NAME                        <addr of register>
`define REG_NAME__BITFIELD1             <bit vector i.e. 1:0>
`deinfe REG_NAME__BITFIELD2             <bit vector i.e. 4:2>

我们使用双下划线来区分寄存器名称和位域。然后我们使用它来执行诸如读取 - 修改 - 写入,屏蔽掉位等等。对于SW,我编写了一个脚本来打印出C格式的.h文件。我想保留类似的格式:

#define REG_NAME                        <addr of register>
#define REG_NAME__BITFIELD1___MASK      0x00000003
#define REG_NAME__BITFIELD1___SHIFT     0
#deinfe REG_NAME__BITFIELD2___MASK      0x0000001c        
#deinfe REG_NAME__BITFIELD2___SHIFT     2

在这种情况下,我想保持REG和BIT_FIELD之间区别的双下划线以及区分MASK / SHIFT /我添加的任何其他内容的三元组。

根据以下SE问题我知道: Use of double underscore in C How is __mro__ different from other double underscore names?

前缀下划线不是一个好的编码习惯。在这样的定义INSIDE中,双重/三重下划线通常是一种糟糕的编码习惯吗?我知道我可以控制宏定义从不以双/三下划线开头或结尾。说实话,这对我有所帮助。当使用所有单个下划线时,我很难找出单词之间的差异。由于存在超过6万个基于寄存器的#defines,我希望有一个更清晰的方式来查看它。然而,如果这是大多数软件工程师所要做的事情,我会尽快改变它(希望)真正的软件工程师会处理大部分事情(不是我介意做SW,这很有趣)。 / p>

如果已经讨论过这个问题,请随时转发该主题。我搜索了大约30-45分钟,但找不到任何似乎完全讨论这个话题的东西。

谢谢!

1 个答案:

答案 0 :(得分:5)

在C和C ++中,你(应用程序程序员)应该避免开始标识符,甚至是一个下划线 - 所有这些标识符至少在某些情况下“保留用于实现”;而不是记住确切的规则,最简单的方法是坚持用字母开始所有标识符。

在C ++ 中,包含两个连续下划线的标识符(如REG_NAME__BITFIELD1___MASK)也会保留用于实现。

因此,就标准而言,您可以在C中执行您想要的操作,但在C ++中不是

作为一种风格,我个人认为你想要连续使用两个下划线的理由(许多类似的标识符在其名称中使用结构,使结构更加明显)是合法的,我不同意相关问题中的人们说,阅读时,很难分辨出一个和两个下划线之间的区别。我不明白你为什么要连续三个下划线,而我认为连续两个和三个下划线之间的区别太难了。

(注意:您链接的旧问题之一是关于Python,这是一种完全不相关的语言;它不能用于得出关于C或C ++的结论。)

(您可以使用以下划线开头的实现定义的标识符,只要它们被记录在案 - 例如__STDC___Bool_IOLBF - 不要自己定义它们,除非文档明确告诉你定义它们(例如_POSIX_C_SOURCE)。在复杂的程序中,“程序”和“实现”之间的界限“可能变得模糊,所以如果你看到一个程序定义以下划线开头的标识符,请不要惊慌失措;作者很有可能确切地知道他们在做什么。”