在C程序中使用_和__[duplicate]

sqougxex  于 2022-12-26  发布在  其他
关注(0)|答案(3)|浏览(126)
    • 此问题在此处已有答案**:

What does double underscore ( __const) mean in C?(4个答案)
What is the reason for underscore in C variable name definition?(3个答案)
八年前就关门了。
我在读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;
}

现在,我读了一段使用__的堆栈溢出代码。sys/syscall. h在Windows中不存在,因此我们必须使用

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

__的确切使用位置以及___之间的区别是什么。

bpzcxfmw

bpzcxfmw1#

the C standard的说明如下(第7.1.3节):

  • 以下划线和大写字母或另一个下划线开始的所有标识符始终保留以供任何使用。
  • 所有以下划线开始的标识符始终保留用作普通和标记名称空间中文件范围的标识符。

(The部分继续列出特定的标识符和由某些标准报头保留的标识符集合)。
这意味着,例如,实现(编译器或标准头文件)可以使用名称__FOO表示 * 任何它喜欢的 *。如果你在自己的代码中定义了这个标识符,你的程序的行为是未定义的。如果你“幸运”,你将使用一个碰巧没有定义它的实现,你的程序将按预期工作。
这意味着您不应该在自己的代码中定义任何这样的标识符(除非您自己的代码是C实现的一部分--如果您不得不问,它不是)。几乎不缺少未保留的标识符。
您可以使用像_foo这样的标识符,只要它是在本地定义的(而不是在文件范围内)--但我个人发现,完全避免使用前导下划线要容易得多。
顺便说一句,你的_sqrt例子并不一定说明这一点,一个实现 * 可能 * 在<math.h>中定义名称_sqrt(因为那里定义的任何东西都在文件作用域),但没有特别的理由期望它会这样做,当我编译你的程序时,我得到一个警告:

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'

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

fcipmucu

fcipmucu2#

这是一个命名约定,这意味着违反这个规则不会立即直接导致程序崩溃,但遵循这个约定是一个非常非常非常非常非常非常[ +无限次]的好主意。
公约的实质是保留:

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

大多数情况下,这也是一个特定于平台的主题,许多供应商都遵守这一约定,但他们也有自己的命名约定和准则。
您可以通过搜索c double underscore naming convention找到更多信息

py49o6xq

py49o6xq3#

tl; dr你弄反了。给你自己的东西命名时不要用下划线,除非你是在为别人写库。标准库和编译器使用这种技术来表示某些名字是内部的,不能直接使用。

强调独特性

C中,没有命名空间。换句话说,包含在文件中的所有名称都可能相互冲突。如果foo.hbar.h都定义了x,则当它们都包含在内时将发生错误。
现在,x是一个非常常见的名称,几乎可以肯定会发生冲突,foo.hbar.h的编写者必须意识到这一点,因此,为了避免将来使用他们代码的程序员出现问题,他们将名称改为_x

替代品

常见名称确实存在。在使用下划线之前,请尝试:
1.在.c.h文件中分离私有变量和公共变量。大多数冲突名称是私有的,不属于头文件。
1.在代码前面加上模块的名称:foo_xbar_x不会冲突。

相关问题