我们在生产中有一些无人关心的构建系统,这些机器运行GCC的古老版本,比如GCC 3或GCC 2.

我也无法说服管理层将其升级到最近的版本:他们说,"如果没有坏掉,就不要修复它".

由于我们维护了一个非常古老的代码库(写于80年代),所以这段C89代码在这些编译器上编译得很好.

但是我不确定用这些旧东西是不是个好主意.

我的问题是:

使用旧的C编译器会损害编译程序的安全性吗?

更新:

同样的代码也是由Visual Studio2008 for Windows target构建的,而msvc目前还不支持C99或C11(我不知道更新的msvc是否支持),我可以使用最新的GCC在我的linux机器上构建它.所以,如果我们换一辆新的GCC,它可能会造得和以前一样好.

推荐答案

实际上,我的观点正好相反.

在很多情况下,C标准没有定义行为,但在给定平台上使用"哑编译器"会发生什么,这是显而易见的.例如允许有符号整数溢出或通过两种不同类型的变量访问同一内存.

gcc(和clang)的最新版本已经开始将这些情况视为优化机会,而不管它们是否会改变二进制文件在"未定义行为"条件下的行为.如果你的代码库是由那些把C当作"可移植汇编程序"的人编写的,这是非常糟糕的.随着时间的推移,在进行这些优化时,优化人员已经开始关注越来越大的代码块,这增加了二进制文件最终执行"由愚蠢的编译器构建的二进制文件"之外的操作的可能性.

有一些编译器switch 可以恢复"传统"行为(我上面提到的两个是-fwrapv和-fno-strict-aliding),但首先您必须了解它们.

虽然原则上编译器错误可以将兼容的代码转换成安全漏洞,但我会认为,在这个宏伟的计划中,这种风险是可以忽略的.

C++相关问答推荐

如何在C中通过转换为char * 来访问float的字节表示?

segfault在C中使用getline()函数

intellisense不工作,甚至已经下载了c/c++扩展

Mbed TLS:OAEP的就地en—/decryption似乎不起作用'

如何在C中只使用一个带双方括号([i][j])访问语法的malloc来分配动态大小的2d数组?

两个连续的语句是否按顺序排列?

当我运行/调试C程序时,Malloc()似乎正在将&q;r\r...&q;赋值给一个指针,我不确定为什么?

仅在给定的大小和对齐方式下正确创建全局

在C++中头文件中声明外部 struct

在编译时参数化类型定义

S的这种管道实施有什么问题吗?

一旦运行长度超过2,编译器是否会优化";strnlen(mystring,32)>;2";以停止循环?

为什么Fread()函数会读取内容,然后光标会跳到随机位置?

接受任何参数的函数指针是否与接受不同参数的函数兼容

Go和C中的数据 struct 对齐差异

`预期说明符-限定符-列表在‘(三元运算符中的’token`‘之前

Realloc():中止的下一个大小无效(核心转储)

C 错误:对 int 数组使用 typedef 时出现不兼容的指针类型问题

System V 消息队列由于某种原因定期重置

C 预处理器中的标记分隔符列表