Unix 和 Linux API 标头是否与C++兼容
Are Unix and Linux API headers compatible with C++?
我之前编写过C++代码来#include
Unix和Linux API标头,这些程序已经产生了预期的行为。也就是说,我不知道这是否可以信赖。C 和 C++ 之间的不兼容性可能会导致有效的 C 标头在C++程序使用时以意外方式运行。
Unix 和 Linux API 标头能否可靠地被将编译为C++的代码使用?
这是这些标题的作者的目标吗?还是这些标头只是有效的 C?
这样做时是否有任何已知的陷阱?
显然,Unix和Linux发行版数量众多,我不希望一个接一个地解决每个发行版的答案。我的期望是,相同的答案将适用于几乎所有的Unix和Linux发行版,例外将证明规则。如果这个假设是错误的,那么对此的解释也将是一个有效的答案。
Unix 标头是指这些:
http://www.unix.org/version3/apis/headers.html
Linux标头是指Linux发行版提供的标头通常作为名为"linux-headers"的包,允许程序与Linux内核交互。例如,这个 Debian 软件包:
https://packages.debian.org/wheezy/kernel/linux-headers-3.2.0-4-amd64
我意识到Unix链接只是一个规范,每个Linux发行版都是不同的,但我再次怀疑对大多数发行版提出这个问题是合理的。如果这不是真的,那么纠正我。
编辑 我的意思只是指用户空间程序使用的标头。
C 标准标头(如 <stdio.h>
、<stdlib.h>
等)在 C++ 标准的附录 D 中指定,其中指出:
这些是已弃用的功能,其中已弃用定义为: 适用于当前版本的标准,但不能保证 在未来的修订中成为标准的一部分。
C标准标头的未弃用C++版本具有<cstdio>
,<cstdlib>
等名称,并且它们在技术上将其定义放入std
(非全局)命名空间中。因此,为了 100% 符合 C++ 规范中未弃用的部分,您需要编写如下内容:
#include <cstdio>
int main() {
std::printf("Hello, world!n");
}
也就是说,据我所知,没有现有的实现实际上迫使你这样做,在我看来,这不太可能。因此,在实践中,您可以安全地在C++中使用 C 标准标头,而无需担心太多问题。
此外,如果您使用的是(例如)POSIX系统,您通常可以同样安全地使用C++的POSIX功能。当然,没有人会故意破坏这些,因为用户会反抗。
然而,在混合范式时,意外破损是可以想象的。如果平台和语言标准都提供了某些功能,则应使用其中之一,但不能同时使用两者。特别是,我不会将 POSIX 线程和同步机制与标准 C++11 线程和同步机制混合使用,因为很容易想象优化器对后者了解太多并生成与前者不兼容的代码。
[更新,稍微详细说明]
<unistd.h>
是我所说的依赖于平台的功能的一个例子。它通常可以从C++开始正常工作,库和编译器开发人员都不会无端破坏它,因为这太烦人了。所以继续打电话给getpid()
或pipe()
或其他什么。
但请注意,混合范式会引发各种问题。仅举几个我脑海中的例子:
- 您可以从信号处理程序调用
new
吗? - 您可以使用描述符 0 上的
dup2
来重定向cin
吗?
在 - 静态初始化期间(即在执行
main
之前)可以安全地调用哪些 POSIX 函数?
这些问题和其他类似的问题都没有通过任何规范来解决。答案取决于您的具体实现,并且可能会因版本而异。
说了这么多...几乎每个重要的C++程序都依赖于某些 C 接口公开的平台特定功能。因此,您描述的内容在实践中会很好地工作,前提是您 (a) 了解"引擎盖下"发生了什么;(b) 有合理的期望;(c)不要试图混合标准和特定于平台的范式。
1)是:"标准标题"是标准的。 无论平台如何,您都可以安全地使用它们。
2) 是:您可以混合使用 C 标头(例如 <stdio.h>
) 带 C++ 标头(例如 <iostream>
)在同一C++翻译单元中。
3)否:您不应该在用户模式程序中使用linux内核头,反之亦然。
Linux 内核标头适用于内核模式驱动程序,而不是"普通"用户空间应用程序。
以下是更多信息:
-
https://unix.stackexchange.com/questions/27042/what-does-a-kernel-source-tree-contain-is-this-related-to-linux-kernel-headers
-
http://kernelnewbies.org/KernelHeaders
- 在提升multi_index容器中,是否定义了"default index"?
- 在C++STL中是否有Polyval(Matlab函数)等价物?
- 检查输入是否不是整数或数字
- 是否可以初始化不可复制类型的成员变量(或基类)
- 在C++中,是否可以基于给定的标识符创建基类的新实例,反之亦然
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 此代码是否违反一个定义规则
- 是否需要删除包含对象的"pair"?
- 是否可以从int转换为enum类类型
- 无论条件是否为true,if总是在c++中执行
- 如何找到大小'x'数组是否完全填充,在C++?
- 检查值是否在集合p1和p2中,但不在p3中
- 是否可以在编译时初始化数组,以便在运行时不会花费时间?
- 检查 std::shared_ptr<> 的当前底层类型是否为 T
- 在c++中检查长方体是否尽可能快地重叠(无迭代)
- GL_SHADERSTORAGE_BUFFER位置是否与其他着色器位置冲突
- 子目录是否继承属性,例如add_definitions,include_directories和父Cmakelist.t
- 标准是否使用多余的大括号(例如 T{{{10}}})定义列表初始化?
- C/C++预处理器是否可以检测一些编译器选项
- 是否可以用"iostream"包装现有的TCP/OOpenSSL会话