防止 std 命名空间之外的标准函数
我只使用特定于 C++ 的头文件(例如 <cstdlib>
),但是我仍然得到全局声明的函数,而不仅仅是 std
中的函数命名空间.有没有办法(也许是编译器开关)来防止这种情况发生?
I am using only header files specific to C++ (e.g. <cstdlib>
), however I still get globally-declared functions, and not just functions in the std
namespace. Is there a way, perhaps a compiler switch, to prevent that?
例如下面的代码:
#include <cstdlib>
float random() { return 0.0f; }
int main() { return 0; }
linux下编译失败,报错:
Fails to compile under linux, with the following error:
> g++ -c main.cpp main.o
main.cpp: In function ‘float random()’:
main.cpp:2:14: error: new declaration ‘float random()’
/usr/include/stdlib.h:327:17: error: ambiguates old declaration ‘long int random()’
或
> clang++ main.cpp -o main.o
main.cpp:2:7: error: functions that differ only in their return type cannot be overloaded
float random() { return 0.0f; }
/usr/include/stdlib.h:327:17: note: previous declaration is here
extern long int random (void) __THROW;
这是由于 stdlib.h
用自己的 random
函数污染"了全局命名空间.
which is caused that stdlib.h
"pollutes" the global namespace with its own random
function.
请注意,在 Windows 上使用 Visual Studio 进行编译时,我不会遇到这些问题.
Note, that I am not facing these problems when compiling on Windows, using Visual Studio.
推荐答案
<cstdlib>
将始终填充 std 命名空间,有时会定义全局符号,而将始终定义全局符号,并且有时填充 std 命名空间.这因实施而异.
<cstdlib>
will always populate std namespace, and sometimes define global symbols, while<stdlib.h>
will always define global symbols, and sometimes populate std namespace. This varies from implementation to implementation.
标准写道:
每个 C 标头,每个都有一个 name.h
形式的名称,其行为就像每个名称都由相应的 cname
标头放置在标准库命名空间中被放置在全局命名空间范围内.未指定这些名称是否首先在命名空间 std
的命名空间范围 (3.3.6) 内声明或定义,然后通过显式 using- 注入全局命名空间范围 -声明 (7.3.3).
Every C header, each of which has a name of the form
name.h
, behaves as if each name placed in the standard library namespace by the correspondingcname
header is placed within the global namespace scope. It is unspecified whether these names are first declared or defined within namespace scope (3.3.6) of the namespacestd
and are then injected into the global namespace scope by explicit using-declarations (7.3.3).
这意味着,编译器被允许将这些符号放入全局范围和 std
命名空间同时.
Which means, that the compiler is allowed to put those symbols into global scope and std
namespace at the same time.
因此,我们认为选择一个头文件优于另一个头文件并没有什么好处.因为它们都极有可能污染全球范围.
Therefore, we see no advantages to prefer one header file over the other. Because they are both very likely to pollute the global scope.
但是,#include <cstdlib>
的时候还是要使用std
命名空间,的时候不要使用
,以确保您的代码可以针对所有编译器实现进行编译.std
>#include <stdlib.h>
However, it is still necessary to use std
namespace when #include <cstdlib>
, and do not use std
when #include <stdlib.h>
, to make sure your code can compile for all compiler implementations.
建议:不要在标准库中使用名称.首先,它们不能保证工作.(注意:当你 #include <csomething>
时,很少有编译器实现实际上保持全局范围干净,所以永远不要依赖它.)其次,它会使代码阅读者和维护者感到困惑,因为几乎每个人都会假设标准名称实际上是标准名称,无论它们来自何处.
Advice: Do not use names in standard libraries. First, they are not guaranteed to work. (Note: Few compiler implementations actually keep the global scope clean when you #include <csomething>
, so never depend on this.) Second, it will confuse code readers and maintainers, because almost everyone will assume standard names are actually standard, no matter where they come from.
相关文章