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

5

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是否忽略了关于废弃的旧样式头文件的标准要求?还是我错误地理解了标准中的措辞?


17.6.2.3.1节允许实现为具有外部链接的C标准库名称提供“extern"C"”链接(尽管建议不要这样做)。如果实现这样做,它将无法定义三个不同版本的 sin() - Crowman
我认为你的意思是<ccmath>必须提供三个版本,因为math.h是C头文件。因此,考虑到这一点,由于sin只有一个版本,而std::sin有三个版本,所以不会有任何重载问题。 - iheanyi
@iheanyi:头文件可以在C和C++之间轻松地进行交叉编译。如果其他方法都不起作用,#ifdef __cplusplus总是可以拯救一天的。 - AnT stands with Russia
可以和不可以。你不能包含<math.h>然后使用std::sin,因为它在math.h中不存在。无论#ifdef __cplusplus是否存在。 - iheanyi
@iheanyi:嗯...这与std::sin有什么特别关系吗?首先,问题是关于math.h中的sin,而不是关于std::sin的。其次,即使它不是主题,C++标准实际上规定math.h可以在命名空间std中提供这些名称(请参见上面的标准引用)。 - AnT stands with Russia
显示剩余2条评论
1个回答

2
感谢@hvd的评论,我看到了光明,原来MSVC是正确的,GCC也应该对歧义进行投诉。
包含与之间唯一的区别在于名称最初所在的作用域不同,前者在命名空间std中,后者在全局命名空间中(实现还可以提供另一个命名空间中的名称,但这并非强制要求),此外,包含C头文件的.h变体已被弃用。

是的,但这与 D.5 所说的一致吗?它基本上表示 math.h 必须提供与 cmath 相同的声明。 - AnT stands with Russia
@AndreyT [headers] "除第18至30条和D附录中注明的内容外,每个头文件cname的内容应与相应的头文件name.h相同[...]". 我猜D.5的措辞有歧义。 - user657267
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - user657267
这并不含糊,也不是你所说的意思。C在<math.h>中指定了double sin(double);。C++指定<cmath>与C的<math.h>类似,除此之外还添加了float sin(float);long double sin(long double);,以及double版本。然后,C++指定<math.h>与C++的<cmath>相似,只是名称在全局命名空间中声明。没有任何迹象表明C++的<math.h>与C的<math.h>匹配。除非您能在标准中找到明确的声明,否则C++的<math.h>需要提供这些覆盖。 - user743382
@user657267 你可以编辑你的回答。彻底改变现有答案的文本通常不受欢迎,但在这种情况下,就像你所说的那样,你没有删除旧答案的选项,所以我认为这是最好的选择。 - user743382
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接