双下划线(__const)在 C 中意味着什么?
-
11-09-2019 - |
题
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
我在 Linux 机器上的 /usr/include/netinet/ether.h 中找到了上述函数定义。
有人可以解释一下 const (关键字)、addr (标识符)和最后的 __THROW 前面的双下划线是什么意思吗?
解决方案
在 C 中,以下划线开头的符号后跟一个大写字母或另一个下划线是为实现而保留的。作为 C 用户,您不应创建任何以保留序列开头的符号。在C++中,限制更加严格;用户不得创建包含双下划线的符号。
鉴于:
extern int ether_hostton (__const char *__hostname, struct ether_addr *__addr)
__THROW;
这 __const
符号的存在是为了允许使用此代码的编译器支持原型符号但没有正确理解 C89 标准关键字的可能性(有点不太可能) const
. 。这 autoconf
宏仍然可以检查编译器是否有工作支持 const
;该代码可以与不支持该支持的损坏的编译器一起使用。
指某东西的用途 __hostname
和 __addr
是对您(标头用户)的保护措施。如果你用 GCC 编译并且 -Wshadow
选项,当任何局部变量隐藏全局变量时,编译器会警告您。如果该函数仅使用 hostname
代替 __hostname
, ,如果你有一个名为 hostname()
, ,就会有阴影。通过使用为实现保留的名称,不会与您的合法代码发生冲突。
指某东西的用途 __THROW
意味着在某些情况下,可以使用某种“抛出规范”来声明代码。这不是标准C;它更像是C++。但只要标头之一(或编译器本身)定义了该代码,就可以与 C 编译器一起使用 __THROW
为空,或为标准 C 语法的某些特定于编译器的扩展。
C 标准 (ISO 9899:1999) 第 7.1.3 节规定:
7.1.3 保留标识符
每个标头声明或定义了其关联子中列出的所有标识符,并选择声明或定义了其关联的将来库中列出的标识符,该指示符始终保留用于任何用途或用于文件范围标识符。
- 所有以下划线和大写字母或其他下划线开头的标识符始终保留用于任何用途。
- 所有以下划线开头的标识符始终保留在普通名称空间和标签名称空间中用作具有文件范围的标识符。
- 以下任何一个子列中的每个宏名称(包括未来库的指示)都保留为使用,如果包括其相关标头(包括其相关标头);除非另有明确说明(见 7.1.4)。
- 所有具有外部链接的标识符在以下任何一个子列中(包括将来的库指示)始终保留作为具有外部链接的标识符。154)
- 在以下任何一个子列中列出的文件范围(包括未来图书馆说明)中列出的每个标识符都保留为宏名称,如果包含了任何关联的标头,则保留使用同名空间的文件范围的标识符。
没有保留其他标识符。如果程序在保留的上下文中声明或定义标识符(除了7.1.4的允许外),或将保留标识符定义为宏名称,则该行为是未定义的。
如果程序删除(用
#undef
)在上面列出的第一个组中,任何宏观定义的标识符,行为是不确定的。脚注 154) 具有外部链接的保留标识符列表包括
errno
,math_errhandling
,setjmp
, , 和va_end
.
也可以看看 在 C++ 标识符中使用下划线的规则是什么;许多相同的规则适用于 C 和 C++,尽管嵌入的双下划线规则仅在 C++ 中,如本答案顶部所述。
其他提示
使用双带下划线的名称被保留用于通过执行使用。这并不一定意味着他们是内部本身,虽然他们经常是。
我们的想法是,你不允许使用任何名称以__
,所以实现自由像宏扩展,或者语法扩展的名字的地方使用它们(如__gcnew
不是C ++的一部分,但微软可以将其添加到C ++ / CLI相信,没有现成的代码应该有这样的事情在这int __gcnew;
,将停止编译)。
要找出这些特定扩展名的意思,即__const
你需要查阅文档为您特定的编译器/平台。在这种特殊情况下,你应该考虑的文档中的原型(例如的 http://www.kernel.org/doc/man-pages/online/pages/man3/ether_aton.3.html )为函数的接口,并忽略__const
和__THROW
装饰品那出现在实际报头中。
通过在一些库惯例,这表示特定的符号是用于内部使用,并不意在库的公共API的一部分。
在__const下划线表示该关键字是编译器扩展,并使用它不是便携式的(关键字const加入到下在以后的修订版,89我想)。 该__THROW也是某种扩展名的,我认为它被定义为,如果用gcc一些__attribute __(东西),但我没把握懒得检查。 该__addr又能代表什么程序员希望它的意思是,这只是一个名字。