11

我目前正在开发一个 C 项目,该项目需要在不同的构建环境之间具有相当的可移植性。该项目针对托管 C 环境中的 POSIX 兼容系统。

实现良好可移植性的一种方法是在符合所选标准的情况下进行编码,但很难确定给定的翻译单元是否严格符合 ISO C。例如,它可能违反某些翻译限制,或者它可能依赖于未定义的行为,而没有来自编译环境的任何诊断消息。我什至不确定是否可以检查大型项目的严格一致性。

考虑到这一点,是否有任何编译器、工具或方法可以在翻译单元的给定标准(例如,C89 或 C99)下测试严格的 ISO C 一致性?

任何帮助表示赞赏。

4

5 回答 5

5

通常不可能找到未定义的运行时行为。例如,考虑

void foo(int *p, int *q)
{
    *p = (*q)++;
    ...

这是未定义的 if p == q。如果不解决停机问题,就无法提前确定是否会发生这种情况。

(已编辑以修复 caf 指出的错误。谢谢,caf。)

于 2010-08-09T21:16:24.730 回答
4

并不真地。C 标准没有对必须接受的翻译单元设置任何绝对最小限制。因此,编写一个完全准确的检查器将是微不足道的,但在实践中完全没用:

#include <stdio.h>

int main(int argc, char **argv) { 
    int i;
    for (i=1; i<argc; i++)
        fprintf(stderr, "`%s`: Translation limit (potentially) exceeded.\n", argv[i]);
    return 0;
}

是的,这拒绝一切,无论多么微不足道。也就是符合标准。正如我所说,它在实践中完全没有用。不幸的是,你真的不能做得更好——当你决定移植到不同的实现时,你可能会遇到一些你以前从未见过的奇怪的资源限制,所以你编写的任何代码(最多包括 " hello world") 可能会超过资源限制,尽管数十甚至数百个编译器允许在/用于更小的系统上。

编辑:

为什么“hello world”程序不严格符合

首先,值得重新说明“严格符合”的定义:“严格符合的程序应仅使用本国际标准中指定的语言和库的那些特性。2)它不应产生依赖于任何未指定、未定义、或实现定义的行为,并且不得超过任何最小实现限制。”

实际上,“Hello, World”没有严格符合的原因有很多。首先,如上所述,实施限制的最低要求是完全没有意义的——尽管必须有一些满足某些限制的程序才能被接受,但没有其他程序必须被接受,即使它甚至没有接近到任何这些限制。考虑到要求的表述方式,(充其量)是否存在不超过任何最低实现限制的程序之类的东西是有待商榷的,因为该标准并没有真正定义任何最低实现限制。

其次,在翻译的第一阶段:“物理源文件多字节字符以实​​现定义的方式映射到源字符集......”(§5.1.1.2/1)。自从“你好,世界!” (或您喜欢的任何变体)在源文件中作为字符串文字提供,它可以(是)以实现定义的方式映射到源字符集。一个实现可以自由地决定(对于一个愚蠢的例子)字符串文字将被 ROT13 编码,只要这个事实被正确记录,它就是完全合法的。

第三,输出通常是通过stdout. stdout是一个文本流。根据标准:“字符可能必须在输入和输出中添加、更改或删除,以符合在主机环境中表示文本的不同约定。因此,字符之间不需要一一对应在流中和在外部表示中的那些。” (§7.19.2/2)因此,实现可以(例如)对输出进行 Huffman 压缩(在星期一、星期三或星期五)。

所以,我们有(至少)三个不同的点,在这些点上来自“Hello,World!”的输出。取决于实现定义的特征——其中任何一个都会阻止它符合严格符合程序的定义。

于 2010-08-09T21:06:35.830 回答
-1

gcc 具有警告级别,将尝试确定 ANSI 一致性的各个方面。但帽子只是一个起点。

于 2010-08-09T21:08:49.180 回答
-1

祝你好运。尽量避免使用有符号整数,因为:

int f(int x) 
{
 return -x;
}

可以调用UB。

于 2010-08-10T05:28:41.177 回答
-1

You might start with gcc -std=c99, or gcc -ansi -pedantic.

于 2010-08-09T21:22:03.577 回答