传统的标准C库头文件和重载的C ++函数

时间:2014-11-06 23:33:11

标签: c++ legacy standard-library

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是否只是忽略了已弃用的旧式标题的标准要求?或者我在某种程度上误解了标准中的措辞?

1 个答案:

答案 0 :(得分:2)

感谢@ hvd&#39的评论,我看到了结果,结果证明MSVC是正确的,GCC也应该抱怨模棱两可。

包括<cmath><math.h>之间的唯一区别是名称最初作用域的位置,前者为namespace std,后者为全局名称空间(实现是免费的)也提供其他命名空间中的名称,但这并不是强制性的,并且不推荐使用包含C标头的.h变体的事实。