繁体   English   中英

C ++标准库头可以包含C标准头吗?

[英]Can a C++ standard library header include a C standard header?

我只能在标准草案N4582中找到

[res.on.headers / 1] C ++标头可能包含其他C ++标头。

似乎没有指定C ++标头是否可以包含C标准标头。

如果允许,即使不包含此标头,使用C标准头中定义的全局名称是否不安全(因为程序可能通过某些C ++标准头隐式包含头)?

D.3节C ++标准的C标准库头使26 C标准头部成为C ++的一部分。 因此,这些是C ++的一部分。 此外,许多其他C标头都遵循语言的共享子集(可能通过#ifdef ing some #ifdef ),使它们成为有效的C和C ++标头。

对于你跟进的问题(名称冲突),是的,它当然可以。 原因是C ++标准库包含C标准库内容的<c:::> C ++标头,标准明确允许它们在全局命名空间中提供名称(除了强制提供它们之外::std )。

此外,根据C ++标准的附录D [depr],C标准库头文件( <:::.h>版本)也是C ++标准库的一部分(尽管已弃用)。 这意味着[res.on.headers] / 1允许C ++标头包含它们。

我的答案来得晚,但增加了其他人没有的东西,所以这里......

简短回答:标准是否允许标准C ++标头包含标准C标头仍然不清楚。

其他答案已正确观察到C ++标准

  • 允许标准的C ++标头
  • 包括标准C ++标头。

目前尚不清楚的是标准C头是否是标准C ++头。 我可以两种方式提供证据。

为什么C头确实是C ++头

在带有GNU标准C库2.24的GCC 6.24上,以下测试无法编译。

#include <iostream>

namespace {
    const int printf {42};
}

int main()
{
    std::cout << printf << "\n";
    return 0;
}

编译器抱怨说,“对'printf'的引用是模棱两可的,”尽管测试缺少一个明确的#include <cstdio>

主要编译器和标准库(如GCC和GNU)的开发人员的判断很难被忽略。

其他答案进一步说明了我不需要在此重复的原因。

为什么C头不是C ++头

在C ++ 17标准(草案这里 ),脚注166,显示如下:

[C] C库设施的C ++头文件可以...定义全局命名空间中的名称。

如果C标题是C ++标题,那么编写这样一个脚注是一种奇怪的方式,不是吗? 相反,我们可以预期脚注会以“C库设施的非<*.h> C ++标题......”开头<*.h>

最后一个观察结果尚无定论,但在[res.on.headers]中,该标准还包括:

C标准库头只应包含其对应的C ++标准库头....

同样,如果在编写单词的人的估计中C头是C ++头,那么编写它们似乎是一种奇怪的方式。

结论:含糊不清

不幸的是,像其他回答者一样,我无法在标准的某种方式中找到明确的答案。 与其他回答者不同,我会得出结论,答案仍然含糊不清。 标准中的相关部分包括[contents],[res.on.headers]和[depr.c.headers]。

意见

如果您想知道哪种替代方案在我看来具有优势证据,那么我倾向于不同意其他答案。 由于引用的原因,我倾向于说标准不允许标准C ++头包含标准C头。 无论如何,这种包含与普通的C ++使用相矛盾,只要这种包含使得匿名全局命名空间更难以使用。 [在我的测试中将printf更改为foo ,然后询问如果未来的标准C库添加了函数foo()会发生什么。 这样的实验说明了麻烦。]

另一方面,打一个人的工具链是没有意义的,不是吗? 在C ++的未来版本澄清之前,我的意思是避免在包含标准库头的源文件中使用匿名全局命名空间。

我怀疑,由于标准已经弃用了使用标准C头的旧样式,标准委员会可能不会过于考虑如何在此期间修补旧样式的问题。 也许C ++ 20模块可以提供一个简洁的解决方案。 我们会看到。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM