C99是否与C89向后兼容?

时间:2009-11-16 01:56:38

标签: c c99

我习惯了旧式的C和最近才开始探索c99的功能。我只有一个问题:如果我在我的程序中使用c99,使用gcc的c99标志并将其与之前的c99库链接,我的程序是否会成功编译?

那么,我应该坚持旧的C89还是进化?

8 个答案:

答案 0 :(得分:9)

我相信他们在这方面是兼容的。只要您正在编译的内容不会踩到任何新的好东西。例如,如果旧代码包含enum bool { false, true };,那么您就遇到了麻烦。作为一个类似的恐龙,我正在慢慢拥抱C99的美妙新世界。毕竟,它现在已经潜伏了大约10年;)

答案 1 :(得分:7)

你应该进化。感谢您的收听: - )

实际上,我会对此进行扩展。

你是对的,C99已经存在了很长一段时间。你(在我看来)将该标准用于遗留代码以外的任何其他内容(你只修复错误而不是添加新功能)。遗留代码可能不值得,但您应该(与所有业务决策一样)进行自己的成本/收益分析。

我已经确保我的新代码与C1x兼容了 - 虽然我还没有使用任何新功能,但我确保它不会破坏。

对于需要注意的代码,标准的作者认真对待非常的向后兼容性。他们的工作不是设计一种新的语言,而是编纂现有的做法。

他们目前所处的阶段使他们在更新语言方面有更多的自由,但他们仍然遵循希波克拉底誓言的输出:“首先,不要伤害”。

通常,如果您的代码被新标准破坏,编译器将被迫告诉您。因此,简单地编译代码库将是一个很好的开始。但是,如果您阅读C99 rationale document,则会看到“安静更改”这一短语 - 这是您需要注意的。

这些是编译器中的行为变化,您不需要了解这些变化,如果您的应用程序开始表现异常,可能会引起很多焦虑和咬牙切齿。不要担心“c89的安静变化” - 如果它们有问题,你就会被它们咬伤。

顺便说一句,该文件是一本很好的读物,可以理解为什么实际标准会说出它所说的内容。

答案 2 :(得分:2)

恭敬地:尝试并找出答案。 :-)

但是,请记住,即使您需要修复一些微小的编译差异,向上移动也许是值得的。

答案 3 :(得分:2)

如果您没有违反显式C99功能,c90代码将与另一个先前的c99库一起运行良好的c99标志。

但是在C89中有一些基于dos的库,这肯定不起作用。

C99非常灵活,因此可以随意迁移: - )

答案 4 :(得分:2)

C库之间的调用约定在很大程度上没有改变,事实上,我不确定它有没有。

此时操作系统严重依赖于C调用约定,因为C API往往是操作系统各部分之间的粘合剂。

所以,基本上答案是“是的,二进制文件将向后兼容。不,当然,使用C99功能的代码以后不能用非C99编译器编译。”

答案 5 :(得分:1)

它旨在向后兼容。它规范了许多供应商已经实施的扩展。有可能,甚至可能,编写良好的程序在使用C99进行编译时不会出现任何问题。

根据我的经验,重新编译一些模块而不是其他模块来节省时间......浪费了很多时间。通常有一些容易被忽视的细节,需要新的编译器才能使它全部兼容。

答案 6 :(得分:1)

某些C89功能无效C99

可以说,这些功能仅出于历史原因而存在,不应在现代C89代码中使用,但确实存在。

The C99 N1256 standard draft前言第5段将C99与旧版本进行了比较,并且是开始搜索这些不兼容性的好地方,即使它有比限制更多的扩展名。

隐式int返回和变量类型

Lutz在评论中提及,例如:以下是有效的C89:

static i;
f() { return 1; }

但不是C99,你必须写:

static int i;
int f() { return 1; }

这也阻止了在C99中调用没有原型的函数:Are prototypes required for all functions in C89, C90 or C99?

n1256说:

  

删除隐式int

返回无空函数的表达式

有效C89,无效C99:

int f() { return; }

我认为在C89中它返回一个实现定义的值。 n1256说:

  

在没有表达式的情况下返回返回值

的函数中不允许的表达式

带负操作数的整数除法

  • C89:转向实施定义的方向
  • C99:舍入为0

因此,如果您的编译器四舍五入到-inf,并且您依赖于该实现定义的行为,那么您的编译器现在必须在C99上破坏您的代码。

https://stackoverflow.com/a/3604984/895245

n1256说:

  

可靠的整数除法

Windows兼容性

一个主要的实际问题是能够在Windows中编译,因为Microsoft does not intend to implement C99 fully too soon

这就是为什么libgit2 limits allowed C99 features

答案 7 :(得分:1)

C89标准的一些部分含糊不清,根据人们如何解释关于指针类型和他们访问的对象的规则,标准可能被视为描述两个中的一个非常非常不同的语言 - 其中一种语义在语义上更强大,因此可用于更广泛的领域,其中一种语言允许更多的机会进行基于编译器的优化。 C99标准"澄清"规则要明确表明它不会强制要求与前一种语言兼容,即使它在许多领域都受到压倒性的支持;它还将C89中定义的一些内容视为未定义,但仅仅是因为C89规则的编写不足以禁止它们(例如,在目标具有堆持续时间的情况下使用memcpy进行类型惩罚)。

因此,C99可能与其作者认为由C89描述的语言兼容,但与大多数C89编译器在整个20世纪90年代处理的语言不兼容。