C++语言标准在D.5中提到:
2 每个C头文件的名称形式为
name.h
,相应的cname
头文件中放置于标准库命名空间的每个名称都被视为放置于全局命名空间范围内。这些名称是否首先在命名空间std
的命名空间范围(3.3.6)内声明或定义,然后通过显式using-declarations(7.3.3)注入到全局命名空间范围内是未指定的。3 [示例:头文件
<cstdlib>
确保在命名空间std
内提供其声明和定义。它还可以在全局命名空间内提供这些名称。头文件<stdlib.h>
确保在全局命名空间内提供相同的声明和定义,就像在C标准中一样。它还可以在命名空间std
内提供这些名称。-结束示例]
这似乎非常明确地说明了(“...每个名称...”、“...相同的声明...”),旧式的<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是否忽略了关于废弃的旧样式头文件的标准要求?还是我错误地理解了标准中的措辞?
sin()
。 - Crowman#ifdef __cplusplus
总是可以拯救一天的。 - AnT stands with Russiastd::sin
有什么特别关系吗?首先,问题是关于math.h
中的sin
,而不是关于std::sin
的。其次,即使它不是主题,C++标准实际上规定math.h
可以在命名空间std
中提供这些名称(请参见上面的标准引用)。 - AnT stands with Russia