gpt4 book ai didi

c - 双下划线 (__const) 在 C 中是什么意思?

转载 作者:太空狗 更新时间:2023-10-29 16:19:13 24 4
gpt4 key购买 nike

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表示法允许这样的可能性(有点不太可能),即与此代码一起使用的编译器支持原型(prototype)表示法,但没有正确理解 C89 标准关键字 const。 . autoconf宏仍然可以检查编译器是否支持 const ;此代码可以与不支持该支持的损坏编译器一起使用。

__hostname的使用和 __addr是对您( header 的用户)的一种保护措施。如果您使用 GCC 和 -Wshadow 编译选项,编译器会在任何局部变量遮蔽全局变量时警告您。如果函数只使用 hostname而不是 __hostname ,并且如果您有一个名为 hostname() 的函数,会有阴影。通过使用为实现保留的名称,不会与您的合法代码发生冲突。

__THROW的使用意味着在某些情况下,可以使用某种“抛出规范”来声明代码。这不是标准 C;它更像是 C++。但是只要其中一个 header (或编译器本身)定义了 __THROW,该代码就可以与 C 编译器一起使用。为空,或为标准 C 语法的某些特定于编译器的扩展。


C 标准 (ISO 9899:1999) 的第 7.1.3 节说:

7.1.3 Reserved identifiers

Each header declares or defines all identifiers listed in its associated subclause, and optionally declares or defines identifiers listed in its associated future library directions subclause and identifiers which are always reserved either for any use or for use as file scope identifiers.

— All identifiers that begin with an underscore and either an uppercase letter or another underscore are always reserved for any use.

— All identifiers that begin with an underscore are always reserved for use as identifiers with file scope in both the ordinary and tag name spaces.

— Each macro name in any of the following subclauses (including the future library directions) is reserved for use as specified if any of its associated headers is included; unless explicitly stated otherwise (see 7.1.4).

— All identifiers with external linkage in any of the following subclauses (including the future library directions) are always reserved for use as identifiers with external linkage.154)

— Each identifier with file scope listed in any of the following subclauses (including the future library directions) is reserved for use as a macro name and as an identifier with file scope in the same name space if any of its associated headers is included.

No other identifiers are reserved. If the program declares or defines an identifier in a context in which it is reserved (other than as allowed by 7.1.4), or defines a reserved identifier as a macro name, the behavior is undefined.

If the program removes (with #undef) any macro definition of an identifier in the first group listed above, the behavior is undefined.

Footnote 154) The list of reserved identifiers with external linkage includes errno, math_errhandling, setjmp, and va_end.


另见 What are the rules about using an underscore in a C++ identifier ;许多相同的规则适用于 C 和 C++,尽管嵌入的双下划线规则仅适用于 C++,如本答案顶部所述。


C99 基本原理

C99 Rationale说:

7.1.3 Reserved identifiers

To give implementors maximum latitude in packing library functions into files, all external identifiers defined by the library are reserved in a hosted environment. This means, in effect, that no user-supplied external names may match library names, not even if the user function has the same specification. Thus, for instance, strtod may be defined in the same object module as printf, with no fear that link-time conflicts will occur. Equally, strtod may call printf, or printf may call strtod, for whatever reason, with no fear that the wrong function will be called.

Also reserved for the implementor are all external identifiers beginning with an underscore, and all other identifiers beginning with an underscore followed by a capital letter or an underscore. This gives a name space for writing the numerous behind-the-scenes non-external macros and functions a library needs to do its job properly.

With these exceptions, the Standard assures the programmer that all other identifiers are available, with no fear of unexpected collisions when moving programs from one implementation to another5. Note, in particular, that part of the name space of internal identifiers beginning with underscore is available to the user: translator implementors have not been the only ones to find use for “hidden” names. C is such a portable language in many respects that the issue of “name space pollution” has been and is one of the principal barriers to writing completely portable code. Therefore the Standard assures that macro and typedef names are reserved only if the associated header is explicitly included.

5 See §6.2.1 for a discussion of some of the precautions an implementor should take to keep this promise. Note also that any implementation-defined member names in structures defined in <time.h> and <locale.h> must begin with an underscore, rather than following the pattern of other names in those structures.

§6.2.1 标识符范围的基本原理的相关部分是:

Although the scope of an identifier in a function prototype begins at its declaration and ends at the end of that function’s declarator, this scope is ignored by the preprocessor. Thus an identifier in a prototype having the same name as that of an existing macro is treated as an invocation of that macro. For example:

    #define status 23
void exit(int status);

generates an error, since the prototype after preprocessing becomes

   void exit(int 23);

Perhaps more surprising is what happens if status is defined

   #define status []

Then the resulting prototype is

   void exit(int []);

which is syntactically correct but semantically quite different from the intent.

To protect an implementation’s header prototypes from such misinterpretation, the implementor must write them to avoid these surprises. Possible solutions include not using identifiers in prototypes, or using names in the reserved name space (such as __status or _Status).

另见 P J Plauger The Standard C Library (1992) 对命名空间规则和库实现的广泛讨论。该书引用的是 C90 而不是该标准的任何更新版本,但其中的大部分实现建议至今仍然有效。

关于c - 双下划线 (__const) 在 C 中是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1449181/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com