在C程序中使用_和__

时间:2014-08-02 01:01:48

标签: c

我正在阅读K& R书。我读到了:

  

...仅供标准库函数使用的名称   以_开头,因此他们不太可能与其中的名字发生冲突   用户程序...

这究竟意味着什么,请解释真实简单实用的方法。

我的理解是:

如果我想使用math.h中定义的sqrt,那么

#include <math.h>
#define sqrt(x) x*x*x

main() 
{ 
int x=4; 
_sqrt(x); // That is from the header file math.h
sqrt(x); // my own defined macro 
/*or its the reverse way _sqrt for my own defined macro so it won't collide with original sqrt i.e. without _ for sqrt from math.h */ 
return 0;
}

现在,我使用__在stackoverflow上读取代码。 Windows中没有sys / syscall.h所以我们必须使用

#if __linux 
#include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif

使用__的确切位置以及b / w __&amp;的区别是什么? _。     在这里输入代码

3 个答案:

答案 0 :(得分:17)

以下是the C standard所说的内容(第7.1.3节):

  • 所有以下划线和大写字母或其他字母开头的标识符 下划线总是保留用于任何用途。
  • 所有以下划线开头的标识符始终保留用作标识符 在普通名称和标签名称空间中都有文件范围。

(该部分继续列出某些标准标题保留的特定标识符和标识符集。)

这意味着,例如,实现(编译器或标准头)可以使用名称__FOO它喜欢的任何内容。如果在自己的代码中定义该标识符,则程序的行为是未定义的。如果你“幸运”,你将使用一个不会定义它的实现,你的程序将按预期工作。

这意味着你不应该在你自己的代码中定义任何这样的标识符(除非你自己的代码是C实现的一部分 - 如果你不得不问,它不是)。无论如何都不需要定义这样的标识符;几乎没有任何未预留的标识符。

你可以使用_foo之类的标识符,只要它在本地定义(不在文件范围内) - 但我个人觉得更容易避免使用前导下划线。

顺便提一下,_sqrt的例子并不一定说明这一点。实现可以_sqrt中定义名称<math.h>(因为那里定义的任何内容都在文件范围内),但是没有特别的理由期望它会这样做。编译程序时,我收到警告:

c.c:7:1: warning: implicit declaration of function ‘_sqrt’ [-Wimplicit-function-declaration]

因为我的系统上的<math.h>没有定义该标识符,并且链接时发生致命错误:

/tmp/cc1ixRmL.o: In function `main':
c.c:(.text+0x1a): undefined reference to `_sqrt'

因为库中没有这样的符号。

答案 1 :(得分:5)

这是一个命名惯例,这意味着违反此规则不会立即直接导致破坏您的程序,但实际上真的真的真的非常[+无限次]一个跟随对话的好主意。

公约的实质是保留:

  • _开头为语言实体命名,其中包括标准库
  • 以编译器内部的__开头命名

在大多数情况下,它也是一个非常特定于平台的主题,许多供应商都尊重这一惯例,但他们也有自己的命名惯例和指南。

您可以搜索c double underscore naming convention

找到更多信息

答案 2 :(得分:0)

<强> TL;博士你倒退了。在没有引导下划线的情况下命名您自己的东西,除非您正在为其他人编写库。标准库和编译器使用该技术来表示某些名称是内部的,而不是直接使用。

唯一性的下划线

C中,没有名称空间。换句话说,文件中包含的所有名称都可能相互冲突。如果foo.hbar.h都定义x,那么当它们都被包含时会发生错误。

现在,x是一个很常见的名字。几乎可以保证碰撞,foo.hbar.h的作者必须意识到这一点。因此,为了避免将来使用其代码的程序员出现问题,他们将名称更改为_x

替代

确实会出现常见名称。在诉诸强调之前,请尝试:

  1. 将私有与.c.h个文件中的公共变量分开。大多数冲突名称都是私有的,不属于标题。

  2. 使用模块名称添加代码:foo_xbar_x不会发生冲突。