[英]Why does an object with static member instantiated in global namespace cause segfault?
[英]Why does including <map> cause the div function to be defined in the global namespace?
考虑以下代码块:
void foo(){
int a = div(1,2);
}
这通常不会编译,因为div
函数尚未声明。 但是,如果我在代码前面加上#include <map>
,代码就会编译。 为什么map
将标识符拉入全局命名空间,为什么特别是div
函数? 有没有办法避免这种情况?
[麦克维]
#include <map>
void foo(){
int a = div(1,2);
}
int main()
{
foo();
}
实时链接 - https://godbolt.org/z/Ye8rv4MTc
clang - <source>:4:7: error: no viable conversion from 'div_t' to 'int'
gcc - <source>:4:11: error: 'div' was not declared in this scope
MSVC - <source>(4): error C2440: 'initializing': cannot convert from 'div_t' to 'int'
任何 C++ 标准库头文件都允许包含任何其他 C++ 标准库头文件。
这些头文件之一是<cstdlib>
,它是<stdlib.h>
C 标准库头文件的 C++ 版本,它声明了函数div_t div(int, int)
。
C 标准库头文件的 C++ 版本通常在std
命名空间中声明所有实体。 然而,该标准允许实现允许他们首先在全局命名空间中声明实体,然后通过using
声明将它们导入std
命名空间。
因此,如果您完全包含任何 C++ 标准库头文件,您必须期望 C 标准库中的任何实体都可以在全局命名空间中声明。 div_t div(int, int)
就是其中之一。
然而,所有这些都是未指定的行为。 如果仅包含<map>
,则无法保证div_t div(int, int)
将被声明(在全局命名空间或std
中)。
如果名称与您要声明自己的某些实体冲突,则解决方案是将您自己的所有东西(除main
)放入您自己的命名空间。 这样,名称查找将更喜欢您在命名空间内的声明,而不是全局命名空间中的声明。 无论如何都应该这样做。 全局命名空间中有许多潜在的陷阱,特别是其中有许多额外的保留标识符、名称、签名等。
不是答案,而是包含 msvc 的信息,因此它似乎确实被拉入了全局命名空间
1>main.cpp
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\map
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\tuple
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\compare
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\bit
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\xstddef
1>Note: including file: ...\VC\Tools\MSVC\14.32.31326\include\cstdlib
1>Note: including file: C:\Program Files (x86)\Windows Kits\10\Include\10.0.20348.0\ucrt\stdlib.h
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.