C89 / C90,C99和C11的兼容性

时间:2017-01-08 18:00:50

标签: c c99 iso c11 c89

我刚读过:C Wikipedia entry。据我所知,有三种不同版本的C被广泛使用:C89,C99和C11。我的问题涉及不同版本的源代码的兼容性。 假设我要编写一个程序(在C11中,因为它是最新版本)并导入一个用C89编写的库。根据C11规范编译所有文件时,这两个版本是否能够正常工作?

问题1 : C的较新版本是旧C版本的C99,C11超集吗?我认为,超集我的意思是,根据较新的C规范编译时,旧代码将编译时没有错误和相同的含义。

我刚才读到,//在C89和C99中有不同的含义。除了这个功能,是C89的C99和C11超集吗?

如果问题1的答案是否定的,那么我又得到了2个问题。

  1. 如何' port'新版本的旧代码?有没有解释这个程序的文件?

  2. 使用C89或C99或C11更好吗?

  3. 提前感谢您的帮助。

    编辑:将ISO C更改为C89。

4 个答案:

答案 0 :(得分:9)

  

C的较新版本是旧版C版本的C99,C11超集吗?

有许多不同之处,大而微妙。大多数更改都添加了新功能和库。 C99和C11不是C90的超集,尽管为确保向后兼容性做了大量工作。然而,C11主要是C99的超集。

从C90移植时,旧的代码可能会中断,以防代码写得不好。特别是各种形式的“隐式int”和隐式函数声明都被禁止使用C99语言。 C11禁止gets功能。

完整的更改列表可以在pdf的C11草案页面13中找到,其中“第三版”是指C11,“第二版”是指C99。

  

如何将旧代码“移植”到新版本?有没有解释这个程序的文件?

我不知道任何此类文件。如果您有良好的代码,移植很容易。如果你有腐烂的代码,移植将是痛苦的。至于实际的移植程序,如果您了解C99和C11的基础知识将很容易,所以最好的办法是找到一个可靠的学习来源,解决C99 / C11。

从C99移植到C11应该毫不费力。

  

使用C89或C99或C11是否更好?

最好使用C11,因为这是当前的标准。 C99和C11都包含各种“语言错误修复”,并引入了新的有用功能。

答案 1 :(得分:1)

在大多数情况下,更高版本是早期版本的超集。虽然尝试使用restrict作为标识符的C89代码将被C99添加具有相同拼写的保留字而被打破,并且在某些情况下,代码被设计为利用解析器来利用某些极端情况这两种语言将被区别对待,其中大部分都不太重要。

然而,更重要的问题与内存别名有关。 C89包括 限制可用于访问某些指针的指针类型的规则 对象。因为规则会使像malloc()这样的函数无效 他们按照书面形式应用于由此创建的对象,大多数程序员和 编译器编写者都将这些规则视为仅适用于有限的情况(我怀疑如果人们没有认为规则只适用于狭义的话),C89就会被广泛接受。 C99声称要“澄清”这些规则,但它的新规则实际上比对旧规则的解释更为广泛,破坏了许多在C89的常见解释下已定义行为的代码,甚至一些代码根据C89明确定义,没有实用的C99等价物。

例如,在C89中,memcpy可用于将与任何类型的对象关联的位模式复制到具有相同大小的任何其他类型的对象,在该位模式将表示的任何情况下目标类型中的有效值。 C99添加了语言,允许编译器以任意方式运行,如果memcpy用于将某种类型T的对象复制到没有声明类型的存储(例如从malloc返回的存储),那么该存储就是读取为与T不兼容的类型的对象 - 即使原始对象的位模式在新类型中具有有效含义。此外,适用于memcpy的规则也适用于将对象复制为字符类型数组的情况 - 没有明确说明这意味着什么 - 所以不清楚究竟需要做什么代码来实现与C89匹配的行为memcpy

在许多编译器上,可以通过在命令行中添加-fno-strict-aliasing选项来解决此类问题。请注意,指定C89模式可能就足够了,因为编译器编写者经常使用相同的内存语义,无论他们应该实现哪种标准。

答案 2 :(得分:0)

通常,较新版本的标准是向后兼容的。

如果没有,您可以使用不同的标准将不同的.c文件编译为不同的.o文件,并将它们链接在一起。这确实有效。

通常你应该使用新代码的最新标准,如果很容易,修复新标准破坏的代码,而不是使用上面的hacky解决方案。

编辑:除非您正在处理可能未定义的行为。

答案 3 :(得分:0)

较新版本的C绝对不是旧版本的严格超集。

一般来说,只有在升级编译器或交换编译器供应商时才会出现这种问题。您必须计划很多次要的代码来处理此事件。在很多时候,新的编译器将捕获旧编译器未确认的问题,以及通过强制执行新的C标准可能发生的轻微不兼容性。

如果可以确定,使用的最佳标准是编译器支持的最佳标准。

C11 wikipedia article详细描述了它与C99的区别。