如何使用-std=gnu99编译Linux内核模块?

11

最近我学会了如何编写简单的字符驱动程序,并在玩弄代码时发现我的C99代码经常会出现大量以下GCC警告:

warning: ISO C90 forbids mixed declarations and code
我猜测这是因为主要的Linux内核Makefile设置了使用非C99标准进行编译。我在网上搜索并在stackoverflow上找到了这个答案:如何使用make并编译为C99?
所以我自然地尝试在我的Makefile中加入以下内容:
ccflags-y := -std=gnu99

不幸的是,这并没有消除GCC警告。我检查了make的详细输出,并验证了GCC确实在末尾使用了-std=gnu99;所以我有点困惑。

我应该如何使用-std=gnu99选项正确编译Linux内核模块?

编辑:

我注意到GCC输出显示了这个选项:-Wdeclaration-after-statement。这就是即使有-std=gnu99选项我还收到警告的原因吗?


Linux的Makefile在你的模块之前被调用,因此GCC可能会混合std=定义。 - stdcall
4
为什么不在函数开始时声明所有变量,这样就可以消除警告了呢? - Gonzalo
1
这可能是因为C99的这个特性(语句后声明)是Linus似乎讨厌的事情之一。因此,Linux编码风格禁止使用它。 - Jens Gustedt
@JensGustedt 这很奇怪,我模糊地记得在Linux内核编码风格文档中提到过,但我现在似乎找不到它了。 - Vilhelm Gray
你提供的答案已经有人回答过了,但是你可能有更好的答案。 - Ciro Santilli OurBigBook.com
1
@Gonzalo 如果你想在正确的时间创建一个常量,比如 const int numTimesFooDone=doFoo();,那么你就会很难实现它。你必须将 numTimesFooDone 保持为非 const,并冒着在稍后某个地方不经意间错误地覆盖它而不注意的风险,例如 if(numTimesFooDone=3)...。这只是从程序员那里剥夺了一些有用的编译器帮助。 - Ruslan
2个回答

21

结果表明,-std=gnu99 实际上起作用了;在删除编译器标志后,我开始看到有关 C99 功能的错误。因此,这意味着除了 -std= 选项之外,其他原因会导致警告消息打印出来。

通过使用 make V=1 解析冗长的输出后,我发现了 -Wdeclaration-after-statement 选项作为 GCC 执行的一部分。这是我看到的 ISO C90 混合声明警告的原因。

要禁用 ISO C90 警告,请将此传递给 GCC:-Wno-declaration-after-statement

例如:

ccflags-y := -std=gnu99 -Wno-declaration-after-statement

0

如果你有 Makefile, 你也可以在里面指定这个标志:

FLAGS=-std=gnu99

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接