我正在读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 上阅读了一段代码,使用__
。 sys/syscall.h 在 Windows 中不存在,所以我们必须使用
#if __linux
#include <sys/syscall.h>
#elif defined(_WIN32) || defined(_WIN64)
#include <windows.h>
#endif
具体在哪里__
使用过,黑白有什么区别__
& _
.
这是什么C标准说(第 7.1.3 节):
- 所有以下划线和大写字母或其他字母开头的标识符
下划线始终保留用于任何用途。
- 所有以下划线开头的标识符始终保留用作标识符
文件范围位于普通名称空间和标记名称空间中。
(本节继续列出由某些标准标头保留的特定标识符和标识符集。)
这意味着,例如,实现(编译器或标准头)可以使用名称__FOO
for 任何它喜欢的东西。如果您在自己的代码中定义该标识符,则程序的行为是未定义的。如果您“幸运”,您将使用一个没有定义它的实现,并且您的程序将按预期工作。
这意味着您根本不应该在自己的代码中定义任何此类标识符(除非您自己的代码是 C 实现的一部分 - 如果您必须询问,它不是)。无论如何,没有必要定义这样的标识符;几乎不缺少未保留的标识符。
您可以使用类似的标识符_foo
只要它是在本地定义的(不在文件范围内)——但我个人发现完全避免使用前导下划线要容易得多。
顺便说一句,你的例子_sqrt
并不一定能说明这一点。一个实现may定义名称_sqrt
in <math.h>
(因为任何定义的东西都在文件范围内),但没有特别的理由期望它会这样做。当我编译你的程序时,我收到警告:
c.c:7:1: warning: implicit declaration of function ‘_sqrt’ [-Wimplicit-function-declaration]
because <math.h>
在我的系统上doesn't定义该标识符和链接时致命错误:
/tmp/cc1ixRmL.o: In function `main':
c.c:(.text+0x1a): undefined reference to `_sqrt'
因为图书馆里没有这样的符号。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)