严格的ISO C一致性测试

时间:2010-08-09 20:56:13

标签: c standards-compliance strict toolchain

我目前正在开发一个C项目,需要在不同的建筑环境中相当便携。该项目面向托管C环境中符合POSIX标准的系统。

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

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

感谢任何帮助。

5 个答案:

答案 0 :(得分:4)

通常无法找到未定义的运行时行为。例如,考虑

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

未定义。在没有解决停止问题的情况下,是否可能发生这种情况无法提前确定。

(编辑修复错误的caf指出。谢谢,咖啡馆。)

答案 1 :(得分:3)

不是真的。 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”程序不严格符合

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

实际上有一个数字的原因“Hello,World”并不严格符合。首先,如上所述,实现限制的最低要求完全没有意义 - 尽管必须有某些程序满足某些可接受的限制,其他程序必须被接受,即使它甚至没有接近任何这些限制。鉴于要求的陈述方式,可以提出质疑(充其量)是否存在任何不超过任何最低实施限制的程序,因为标准并未真正定义任何最低实施限制。

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

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

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

您可以从gcc -std=c99gcc -ansi -pedantic开始。

答案 4 :(得分:0)

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

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

可以调用UB。