C ++语言标准在 D.5
中说2 每个C标头,每个标头都有
name.h
形式的名称,表现得很好 好像每个名称都放在标准库命名空间中 相应的cname
标头位于全局命名空间内 范围。未指定是否首先声明这些名称或 在命名空间std
的命名空间范围(3.3.6)内定义并且是 然后通过explicit注入全局命名空间范围 使用声明(7.3.3)。3 [示例:标题
<cstdlib>
确实在其中提供了声明和定义 名称空间std
。它也可能在全球范围内提供这些名称 命名空间。标题<stdlib.h>
肯定提供相同的标题 全局命名空间中的声明和定义,就像在 C标准。它还可以在命名空间中提供这些名称std
。 - 例子]
这似乎明确地说明了(&#34; ......每个名字......&#34;,&#34; ......相同的声明...&#34;)旧式<name.h>
标头必须提供与新样式<cname>
标头相同的声明集,但在全局命名空间中。例如,对于C ++特定的各种C函数的重载版本,没有例外。
这似乎意味着<math.h>
必须在全局命名空间中提供三个版本的sin
函数:sin(float)
,sin(double)
和sin(long double)
。反过来,这意味着以下C ++代码应该失败重载解析
#include <math.h>
int main() {
sin(1);
}
它在MSVC ++编译器下失败,但它在GCC和Clang下成功编译。那么,GCC是否只是忽略了已弃用的旧式标题的标准要求?或者我在某种程度上误解了标准中的措辞?
答案 0 :(得分:2)
感谢@ hvd&#39的评论,我看到了结果,结果证明MSVC是正确的,GCC也应该抱怨模棱两可。
包括<cmath>
与<math.h>
之间的唯一区别是名称最初作用域的位置,前者为namespace std
,后者为全局名称空间(实现是免费的)也提供其他命名空间中的名称,但这并不是强制性的,并且不推荐使用包含C标头的.h
变体的事实。