Unix 和 Linux API 标头是否与C++兼容

Are Unix and Linux API headers compatible with C++?

本文关键字:是否 C++ 兼容 Linux API Unix      更新时间:2023-10-16

我之前编写过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