GCC 15默认会把警告视为错误吗?

编程语言 2026-07-10

在从源码编译安装的GCC 15.2.0中,我遇到了把警告当作错误处理的问题。例如,考虑下面这个C 程序:

int main(void){
    char *yy = 'a';
}
gcc a.c

a.c: In function 'main':
a.c:2:20: error: initialization of 'char *' from 'int' makes pointer from integer without a cast [-Wint-conversion]
    2 |         char *yy = 'a';
      |                    ^~~

最终输出如下:

gcc -Wno-int-conversion a.c

我是否能够将GCC的行为还原为默认不把警告当作错误?也就是说,不需要我显式指定 -Wno-int-conversion

我正在尝试编译MPlayer,但一直失败;如果使用系统自带的GCC(在OSX 10.13上)则能成功。

解决方案

这是GCC 14的一个改动,其中某些警告现在被视为错误。关于这一点,请参阅GCC的 Porting to GCC 14

GCC不再在赋值中把整数类型和指针类型视为等价(包括对函数参数和返回值的隐式赋值),而是因类型错误导致编译失败。

对此在同一页的较早部分给出的解释是:

最初的ISO C标准及其1999年修订版剥夺了对许多C 语言特性的支持,这些特性曾被广泛认为是应用程序错误的源头,因为容易被误用。为了向后兼容,GCC 13及更早版本对这些特性使用诊断仅为警告。尽管在许多版本中这些警告已经默认开启,但经验表明这些警告容易被忽略,从而导致难以诊断的错误。在GCC 14中,这些问题现在会作为错误报告,并且不会生成输出文件,从而为程序员提供更清晰的错误反馈。

关于将错误“转回”为警告的建议,请参见 turning errors back to warnings,即使用命令行选项。影响最小的选项是 -Wno-error=int-conversion,它把 "error" 改为 "warning"。你发现的选项 -Wno-int-conversion 的影响更大,因为它会完全禁用该检查。更大的改动是使用 -fpermissive,这可能是让现有代码库编译通过的最佳选项(不过对新开发而言可能更宽松)。

如果你想在不添加编译器标志的情况下编译MPlayer,你要么修正代码,要么降级到GCC 13.4或更早版本。(大概因为该项目能够成功编译,所以系统上的GCC应为13.4或更早版本。)我会检查这个项目的构建系统,看看是否可以在编译命令中添加 -fpermissive。GCC的“errors back to warnings”文档为此提供了以下指导:

一些构建系统并不会把 CFLAGS 变量传递给构建的所有部分,可能需要把 CC 设置为类似 gcc -fpermissive 的值。若构建系统不支持在 CC 变量中使用空格,可能需要一个包装脚本,如下所示:

```bash

!/bin/sh

exec /usr/bin/gcc -fpermissive "$@" ```

(根据需要调整 gcc 的位置。然后把该包装脚本作为你的编译器使用,而不是 gcc。)

站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。

相关文章