【问题标题】:What C program behaves differently in run-time when compiled with C89 and C99?使用 C89 和 C99 编译时,哪些 C 程序在运行时表现不同?
【发布时间】:2011-12-31 01:23:26
【问题描述】:

我发现以下 sn-p(我认为是在 Wikipedia 中)在识别 C++ cmets 时创建了不同的运行时:

int a = 4 //* This is a comment, but where does it end? */ 2
  ;

但到目前为止,这是唯一的一个(不包括变体)。

我对使用 __STDC__ 等进行区分不感兴趣,对 C89 无法编译的程序也不感兴趣。

是否有其他程序/sn-ps 使用 C89 产生与 C99 不同的运行时?

【问题讨论】:

  • 我认为整数文字类型的规则略有变化,因此您可能会编写一个表达式具有错误符号的程序,因此根据 C89 与 C99 的不同行为会有所不同...
  • @R.. 任何指向源的指针?我会自己弄清楚,但指向来源的指针会有所帮助。
  • 对不起,这就是为什么我把它写成评论而不是答案。 :-)
  • 我认为标准委员会花了很多精力来实现向后兼容性。如果您发现与您引用的不同,则应提交缺陷报告。
  • 致投票结束这个问题的人:想象一下当你必须调试别人的代码,而你不知道他们最初依赖哪个编译器时会发生什么。

标签: c language-lawyer c99 c89


【解决方案1】:

此程序将在符合 C89 的实现上打印 0.000000,在符合 C99 的实现上打印1.000000

#include <stdio.h>
#include <stdlib.h>

int main()
{
    double d = strtod("0x1", NULL);
    printf("%f\n", d);
    return 0;
}

【讨论】:

  • +1 太棒了! C89 停在x 并且只转换零(因为十六进制数字支持在 C99 中是新的),而 C99 转换十六进制数字 1。谢谢,这就是我要找的!
  • @JohanBezem:请注意,实际上,纯 C89 标准库似乎越来越少。
  • 我不打算在实时代码中使用它。而且我在嵌入式,非常古老的编译器偶尔会在那里生存。
【解决方案2】:

两个例子:

  • C99 将-3/2 定义为行为(即截断为零)。

  • C99 将 -1&lt;&lt;1 定义为未定义行为(但 C89 没有)。

此外,过去我遇到过 64 位枚举的问题,例如 enum {mask = 1ULL &lt;&lt; 32},但我不记得编译器是否静默,或者只是默默地做错了事。

【讨论】:

  • AFAIK long long 不在 C89 标准中。我将评估其他两个示例,谢谢!
  • 即使在 C99(以及 C1x)中,枚举也仅限于 int 范围内的值
  • @Christoph True,但许多编译器会支持这样的一些偏差。
  • @JosephQuinsey 您的两个示例是正确的,但符合 C89 的编译器可能会解释与符合 C99 的编译器 AFAICT 相同的表达式。这将使它成为一个不可靠的测试,尽管它是一个有效的测试。不管怎么说,还是要谢谢你! +1
【解决方案3】:

整数除法会产生不同的结果,具体取决于您使用的 c89 实现。

Does either ANSI C or ISO C specify what -5 % 10 should be?

【讨论】:

  • 但是 C89 实现可以实现 C99 语义,因此这不是一种可靠的区分方式。
猜你喜欢
  • 2015-09-15
  • 2011-01-17
  • 2011-01-08
  • 1970-01-01
  • 2011-02-14
  • 1970-01-01
  • 1970-01-01
  • 2010-11-01
  • 2012-08-15
相关资源
最近更新 更多