应该"可移植"C编译为C++吗?

unw*_*ind 19 c c++ compatibility portability

我在一个C问题上发表的答案得到了评论,评论者建议将代码编写为使用C++编译器进行编译,因为最初的问题提到代码应该是"可移植的".

这是"便携式C"的常见解释吗?正如我在对该答案的进一步评论中所说的那样,对我来说完全令人惊讶,我认为可移植性意味着完全不同的东西,并且在编写也是合法C++的C代码时看到的好处很少.

Dev*_*lar 18

目前的C++(1998)标准包含C(1989)标准.关于类型安全的一些精细打印放在一边,这意味着"好"C89应该在C++编译器中编译好.

问题是,当前的C标准是1999年(C99) -这是不是还没有正式的C++标准的一部分(据我所知)(*).这意味着许多C++编译器支持的C99(long long int,stdint.h,...)的许多"更好"的特性并不严格遵守.

"Portable"C完全意味着其他东西,与官方的ISO/ANSI标准没什么关系.这意味着您的代码不会对主机环境做出假设.(int,endianess,非标准函数或errno数字的大小,类似的东西.)

从我曾为一个跨平台项目编写的编码风格指南:

跨平台DNA(不要假设)

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

(*):在撰写本文时这是真的.事情已经改变了一点C++ 11,但我的答案的要点是正确的.

  • 好的清单.当你同时提到int/short/char的大小等等时,我不确定你的意思是"没有本机数据类型".为什么提到尺寸,如果它们不存在/不应该使用?另外,与C&C++之间的类型安全类型相比,存在一些更大的差异 (2认同)
  • 很好的规则,尽管是否存在过 'a'-'A' != 'z'-'Z' 的系统?即使 EBCDIC 也没有那么糟糕...... (2认同)

Pet*_*ham 16

不.我的回答为什么人为地将您的代码限制为C?有一些符合标准的C99不能编译成C++的例子; 早期的C差异较小,但C++具有更强的类型和对(void)函数参数列表的不同处理.

至于将C'移植到C++是否有好处 - 该答案中引用的特定项目是基于特征的语言的虚拟机,因此不适合C++对象模型,并且有很多案例您在哪里拉动void*解释器的堆栈,然后转换为表示内置对象类型布局的结构.为了使代码"可移植"到C++,它会添加大量的转换,这对类型安全没有任何作用.

  • 如果你有一个C编译器,如果你编写C语言是浪费时间,可能会导致错误(养成额外强制转换以使C++编译器开心的习惯意味着你更有可能执行无效的强制转换) ,并阻止您使用C的某些功能,尤其是C99功能.如果你正在编写可移植的C89,那么你只能使用一小部分功能,其中大部分功能都是C++,但必须特别注意可移植性,因为规范的更多部分是实现变量. (3认同)

Sim*_*son 8

可移植性意味着编写代码以便使用不同的编译器和/或不同的平台进行编译并具有相同的行为(即尽可能依赖ISO标准规定的行为).

使用不同语言的编译器进行编译是一个很好的(也许),但我不认为这是可移植性的意思.由于C++和C现在越来越分散,这将更难实现.

另一方面,当编写C代码时,我仍然会避免使用"class"作为标识符.