函数宏中参数名称前面的下划线是否有重要性?

3

我经常遇到一些预处理宏的参数名称以下划线开头; 例如,在Linux内核中:

#define DEVICE_ATTR(_name, _mode, _show, _store) \
struct device_attribute dev_attr_##_name = __ATTR(_name, _mode, _show, _store)

这些参数似乎表现得就像普通的宏参数一样,所以我想不出为什么作者决定在每个参数名称前加一个下划线。与_name连接是否有重要意义,还是下划线只是作者选择使用的约定?


2
@H2CO3 下划线后面跟着小写字母的变量名应该没问题,只有 __ATTR 是可疑的。 - Sergey Kalinichenko
3
那个答案中引用了标准文件的内容:“所有以下划线开头的标识符都被保留,用于普通和标签名称空间中具有文件作用域的标识符”,对我来说,这也算是被保留的。 - user529758
4
@H2CO3 但是宏参数并不是标识符。因此,尽管可能会让人感到不舒服,但据我所知并没有侵犯任何保留权利。 - Daniel Fischer
1
操作系统还希望隐藏实现细节,不让用户空间知道。一些内核头文件是为了导出到用户空间而设计的,并且它们以下划线为前缀,以避免名称冲突。这些信息可以通过简单的查看获得。另请参见headers_check.pl。在内核中使用POSIX是不被赞同的;-)。你问了很多关于Linux内核的问题。Vilhelm's Linux kernel questions - artless noise
1
当然,attributesgcc特有的。你会发现有很多链接器部分的黑科技和其他非标准C的东西(例如init_call等)。我喜欢爱德华·D·威林克(Edward D. Willink)的Fog论文。其中一部分描述了系统设计模式;即,在源代码中无处不在的事物。在Linux中有很多违反规则的基础设施,就像代码生成工具;Qt的mocc-frontkbuild等。这在GNU工具、管道和其他Unix shell哲学下尤其容易实现。 - artless noise
显示剩余10条评论
1个回答

2

不,这些都是普通的标识符,没有特殊意义。我猜作者为什么要这样添加下划线是为了使这些属性的组成更加易读:

dev_attr_##_name

比起其他语言,中文更易于阅读。
dev_attr##name

然而,__ATTR看起来有些可疑:在C语言中,以下划线开头,后跟大写字母或另一个下划线的标识符被保留给实现者使用。在这种情况下,是两个下划线,因此我预计__ATTR是一个系统宏。

__ATTR同样让我感到困惑,但源代码显然有一个定义:http://lxr.free-electrons.com/source/include/linux/sysfs.h?v=3.2#L70 - Vilhelm Gray
3
如果这个信息是从设备驱动程序的头文件中来的,那么它应该是可以接受的:这些头文件与其编译所属的系统紧密相关;无论如何,它们并不旨在具有可移植性。 - Sergey Kalinichenko
2
Linux是实现的一部分。gcc通常由tupleGNU三元组来标识;操作系统libc代码生成器通常是实现的一部分。操作系统libc代码生成器需要协调,以避免彼此覆盖符号。操作系统代码本质上是不可移植的。快速查看sysfs.h表明它正在使用指定初始化,并且_xxx被分配给结构成员xxx;如果名称相同,则宏将无法工作。 - artless noise

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