C语言 在 C 程序中使用 _ 和 __
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/25090635/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
use _ and __ in C programs
提问by Keith Thompson
I was reading K&R book. I read:
我在读 K&R 的书。我读:
...name intended for use only by functions of the standard library begin with
_so they are less likely to collide with the names in the user program...
...名称仅供标准库的函数使用以开头,
_因此它们不太可能与用户程序中的名称冲突...
What does this exactly means please explain real simple and practical way.
这究竟是什么意思,请解释真正简单实用的方法。
What i understood is:
我的理解是:
if i want to use sqrt defined in math.h then
如果我想使用 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;
}
Now, I read a code on stackoverflow using __. sys/syscall.h is not present in windows so we have to use
现在,我使用__. sys/syscall.h 在 windows 中不存在,所以我们必须使用
#if __linux
#include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
Where exactly is __used and what's the difference b/w __& _.
enter code here
究竟在哪里__使用以及 b/w __& 有什么区别_。在此处输入代码
回答by Keith Thompson
Here's what the C standardsays (section 7.1.3):
这是C 标准所说的(第 7.1.3 节):
- 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.
- 所有以下划线和大写字母或另一个下划线开头的标识符始终保留供任何使用。
- 所有以下划线开头的标识符始终保留用作普通名称空间和标记名称空间中具有文件范围的标识符。
(The section goes on to list specific identifiers and sets of identifiers reserved by certain standard headers.)
(该部分继续列出某些标准标头保留的特定标识符和标识符集。)
What this means is that for example, the implementation (either the compiler or a standard header) can use the name __FOOfor anything it likes. If you define that identifier in your own code, your program's behavior is undefined. If you're "lucky", you'll be using an implementation that doesn't happen to define it, and your program will work as expected.
这意味着,例如,实现(编译器或标准头文件)可以将名称__FOO用于任何它喜欢的名称。如果您在自己的代码中定义该标识符,则程序的行为是未定义的。如果您“幸运”,您将使用一个碰巧没有定义它的实现,并且您的程序将按预期工作。
This means you simply should not define any such identifiers in your own code (unless your own code is part of a C implementation -- and if you have to ask, it isn't). There's no need to define such identifiers anyway; there's hardly any shortage of unreserved identifiers.
这意味着您根本不应该在您自己的代码中定义任何此类标识符(除非您自己的代码是 C 实现的一部分——如果您必须询问,它不是)。无论如何都不需要定义这样的标识符;几乎不缺少无保留标识符。
You can use an identifier like _fooas long as it's defined locally (not at file scope) -- but personally I find it much easier just to avoid using leading underscores at all.
你可以使用一个标识符_foo,只要它是在本地定义的(不是在文件范围内)——但我个人发现完全避免使用前导下划线要容易得多。
Incidentally, your example of _sqrtdoesn't necessarily illustrate the point. An implementation maydefine the name _sqrtin <math.h>(since anything defined there is at file scope), but there's no particular reason to expect that it will do so. When I compile your program, I get a warning:
顺便说一下,你的例子_sqrt不一定能说明这一点。一个实现可以定义名称_sqrtin <math.h>(因为在那里定义的任何东西都在文件范围内),但没有特别的理由期望它会这样做。当我编译你的程序时,我收到一个警告:
c.c:7:1: warning: implicit declaration of function ‘_sqrt' [-Wimplicit-function-declaration]
because <math.h>on my system doesn'tdefine that identifier, and a link-time fatal error:
因为<math.h>在我的系统上没有定义那个标识符,还有一个链接时致命错误:
/tmp/cc1ixRmL.o: In function `main':
c.c:(.text+0x1a): undefined reference to `_sqrt'
because there's no such symbol in the library.
因为图书馆里没有这样的符号。
回答by user2485710
It's a naming convention, this means that violating this rule will not immediately and directly lead to breaking your program, but it's a really really really really really really [ + infinite times ] a good idea to follow the convetion.
这是一个命名约定,这意味着违反此规则不会立即直接导致破坏您的程序,但遵循约定确实是一个非常非常非常非常[+无限次]的好主意。
The essence of the convention is to reserve :
约定的本质是保留:
- naming starting with
_for the language entities, which includes the standard library - naming starting with
__for the compiler internals
_以语言实体开头的命名,其中包括标准库__以编译器内部命名开头
it's also a really platform specific topic most of the times, many vendors respect this convention but they also have their own naming conventions and guidelines .
大多数时候它也是一个真正的平台特定主题,许多供应商尊重这个约定,但他们也有自己的命名约定和指南。
You can find more by search for c double underscore naming convention
您可以通过搜索c 双下划线命名约定来找到更多信息
回答by slezica
tl; drYou got it backwards. Name your own stuff without leading underscores, unless you're writing a library for someone else. The standard library and compilers use the technique to signal that certain names are internal, and not to be used directly.
tl; 博士你倒退了。命名您自己的内容时不要使用下划线开头,除非您正在为其他人编写库。标准库和编译器使用该技术来表示某些名称是内部的,不能直接使用。
Underscores for Uniqueness
唯一性的下划线
In C, there are no namespaces. In other words, all names included into a file can collide with each other. If foo.hand bar.hboth define x, an error will occur when they are both included.
在 中C,没有命名空间。换句话说,包含在文件中的所有名称都可能相互冲突。如果foo.h和bar.h都定义x,当它们都包含时会发生错误。
Now, xis a pretty common name. Collision is almost guaranteed, and the writers of foo.hand bar.hmust realize that. So, in the interest of avoiding future problems for the programmers that will use their code, they change the name to _x.
现在,x是一个很常见的名字。碰撞几乎是肯定的,foo.h并且bar.h必须意识到这一点。因此,为了避免将来使用其代码的程序员出现问题,他们将名称更改为_x.
Alternatives
备择方案
Common names do occur. Before resorting to underscoring, try:
常见名称确实出现。在诉诸下划线之前,请尝试:
Separating private from public variables in
.cand.hfiles. Most clashing names are private, and don't belong in the header.Prefixing your code with the name of the module:
foo_xandbar_xwon't collide.
将
.c和.h文件中的私有变量与公共变量分开。大多数冲突名称是私有的,不属于标题。使用模块名称作为代码前缀:
foo_x并且bar_x不会发生冲突。

