c++ - "portable"C 是否应该编译为 C++?

标签 c++ c compatibility portability

我收到了对 an answer 的评论我发布了一个 C 问题,评论者建议应该编写代码以使用 C++ 编译器进行编译,因为最初的问题提到代码应该是“可移植的”。

这是对“可移植 C”的常见解释吗?正如我在对该答案的进一步评论中所说,这让我感到非常惊讶,我认为可移植性意味着完全不同的东西,并且认为编写也是合法 C++ 的 C 代码几乎没有什么好处。

最佳答案

当前的 C++ (1998) 标准合并了 C (1989) 标准。抛开一些关于类型安全的细则,这意味着“好的”C89 应该在 C++ 编译器中编译得很好。

问题在于当前的 C 标准是 1999 年 (C99) 的标准 - 不是 尚未正式成为 C++ 标准 (AFAIK)(*) 的一部分。这意味着 C99 的许多“更好”的特性(long long int、stdint.h、...)虽然被许多 C++ 编译器支持,但在严格意义上是合规。

“可移植”C 完全是另外一种意思,与官方 ISO/ANSI 标准几乎没有关系。这意味着您的代码不会对主机环境做出假设。 (int 的大小、字节序、非标准函数或 errno 数字,诸如此类。)

来 self 曾经为一个跨平台项目编写的编码风格指南:

跨平台 DNA(请勿假设)

  • 没有 native 数据类型。您可能使用的唯一数据类型是标准库中声明的数据类型。
  • char、short、int 和 long 的大小各不相同,就像 float、double 和 long double。
  • int 不是 32 位。
  • char 既没有签名也没有无符号。
  • char 不能容纳数字,只能容纳字符。
  • 将短类型转换为长类型 (int -> long) 会破坏 CPU 的对齐规则。
  • int 和 int* 的大小不同。
  • int* 和 long* 的大小不同(与指向任何其他数据类型的指针一样)。
  • 您还记得 native 数据类型甚至不存在吗?
  • 'a' - 'A' 不会产生与 'z' - 'Z' 相同的结果。
  • 'Z' - 'A' 不会产生与 'z' - 'a' 相同的结果,并且不等于 25。
  • 除了测试它的值之外,你不能对 NULL 指针做任何事情;取消引用会导致系统崩溃。
  • 涉及有符号和无符号类型的算术不起作用。
  • 数据类型的对齐规则随机变化。
  • 数据类型的内部布局随机变化。
  • 上溢和下溢的具体行为随机变化。
  • 函数调用 ABI 随机变化。
  • 按随机顺序计算操作数。
  • 只有编译器才能解决这种随机性。随机性会随着 CPU/OS/编译器的下一个版本而改变。
  • 对于指针,== 和 != 仅适用于指向完全相同数据类型的指针。
  • <, > 仅适用于指向同一数组的指针。它们仅适用于 char 显式声明的 unsigned。
  • 你还记得原生数据类型不存在吗?
  • size_t(sizeof 返回值的类型)不能转换为任何其他数据类型。
  • ptrdiff_t(一个指针减去另一个指针的返回值的类型)不能转换为任何其他数据类型。
  • wchar_t(“宽”字符的类型,其确切性质由实现定义)不能转换为任何其他数据类型。
  • 任何 ..._t 数据类型都不能转换为任何其他数据类型

(*):在撰写本文时确实如此。 C++11 发生了一些变化,但我的回答的要点是正确的。

关于c++ - "portable"C 是否应该编译为 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/713042/

相关文章:

ios - Firebase 5.0.0+ 与 iOS 7.0

c++ - 没有或有静态设备上下文的 OpenGL 加载纹理?

c++ - 检查输入类型失败,C++

模板对象的 C++ 继承(G++ 编译器)

c - 什么是更好的方法来做到这一点?摩尔斯电码程序

javascript - createRange 在 Chrome 中不起作用

c++ - 如何在 clang::VarDecl 中获取变量名的位置

c - 读取位置位置 0x1D5C4C2F 访问冲突

c++ - 如何将 goto 标签存储在数组中,然后跳转到它们?

google-maps - Apple Maps 和 Google Maps API 的参数相同吗?