严格的 C90 代码的 GCC 选项?
Posted
技术标签:
【中文标题】严格的 C90 代码的 GCC 选项?【英文标题】:GCC options for strict C90 code? 【发布时间】:2014-12-17 14:22:54 【问题描述】:我试图找出在测试 strict C90 一致性时要使用的 gcc 标志组合是什么。根据之前的帖子:GCC options for strictest C code?,我应该只需要一个--std=c90。
但这是我尝试过的:
$ cat t.c
#include <stdint.h> /* added in C99 */
int main()
uint64_t t;
return 0;
$ gcc -std=c90 -ansi -pedantic t.c
上述方法运行良好(没有产生警告/错误)。
有谁知道:
-
gcc 标志具有严格的 ISO/IEC 9899:1990 一致性
具有不同标志集的不同编译器(tcc、clang...)?
编辑:
对不起我的措辞,是的,我真的很想模仿一个严格符合 C90 的编译器,换句话说,如果代码尝试使用以后添加的任何功能(想到 C99),它应该会失败。所以pthread
包含头文件应该 在以GNU/GCC calls C90 mode 编译时发出警告(就像 stdint.h 头文件应该在没有 C99 的情况下产生警告)。 -pedantic 很好地警告我long long
的使用,我不明白为什么它不应该警告我uint64_t
。
我使用了 ISO/IEC 9899:1990 的术语,引用自:
http://en.wikipedia.org/wiki/C_(programming_language)#ANSI_C_and_ISO_C1990 年,ANSI C 标准(带有格式更改)被 国际标准化组织 (ISO) 作为 ISO/IEC 9899:1990,有时也称为 C90。因此,术语“C89” 和“C90”指的是同一种编程语言。
EDIT2:
GCC 文档其实很清楚:
C99 标准中的某些功能被接受为 C90 模式下的扩展,以及 C11 中的一些功能 标准被接受为 C90 和 C99 模式中的扩展。
所以我的问题被改写为:
在 Linux 系统上是否有编译器 + 标准包含头文件,严格符合 C90?【问题讨论】:
请注意,C90 是在 ISO/IEC 9899 标准中指定的。您要求 ISO/IEC 9945-1 是 POSIX 标准。 我还没有听说过允许你检查这个的编译器。一些编译器,例如 gcc 和 clang 以及 3.party 标准库,在相当长的时间内支持所请求的标准,特别是在语言级别,但它们并不意味着是合规检查器。对于库功能,它甚至更没有实际意义,因为 C 允许非标准库/头文件可用,没有什么能阻止实现在 c89 编译器中提供 stdint.h - 例如gcc 和 clang 不提供库/头文件 - 留给 3. 方(通常是 linux 上的 glibc) 你说应该发出警告,你的证据呢?梳理标准后,我看不到任何地方说需要编译器来发出诊断。 @malat<stdint.h>
中没有任何内容应该无法在 C90 模式下编译。允许实现为它不提供的相应类型省略任何类型定义/宏。如果您尝试在 C++03 中包含 C++11 标头,编译器本身不会发出诊断信息,而是 GCC 在标头文件中有 #error
pragma。
我猜维护标头的人可以通过添加#if (__STDC_VERSION__ < 199901 && __PEDANTIC__)
之类的内容,然后向例如#error
指令添加类似的东西来轻松实现这一点。 stdint.h
。然而,他们是否会这样做是值得怀疑的,因为我认为绝大多数用户并不真正需要该功能,而且他们可能不会为“以防万一”修补两打标题。当然,您可以随时尝试提交补丁。
【参考方案1】:
C90 合规性并不意味着编译器不能提供 C90 标准中未提及的 other 标头。 (例如,sys/socket.h
。)如果您出于某种奇怪的原因想要禁止这些,您可以通过 -I
选项来添加额外的包含路径,并在该路径中放置所有 C99 标头的版本,这些标头是只需#error Don't include me
。
【讨论】:
“出于某种奇怪的原因”——原因一点也不奇怪。如果 OP 想要测试他们的代码以确保它没有任何 C99 或 OS 特定的依赖项,那么他们绝对确实希望限制自己使用这些标头。 编译器也可以解析给定的标头,解析宏(如果有),并且不包含任何内容,因为在扩展宏并评估条件后,标头不会生成任何文本/code 作为传递给编译器的选项的结果而包含在内。毕竟,使用#ifdef
或ifndef
或其他选项来保护您的标头免受不必要的包含并不难。
@TheParamagneticCroissant 我不知道有任何专门用于禁止 C99 构造的编译器/运行时。那将是一个完全没有回报的编译器来维护。即使在 GCC 提供的 C90 头文件中,我也可以肯定有些函数定义不是 C90 标准的一部分。【参考方案2】:
请记住,GCC 本身是符合指定的 C 标准的独立实现;这样的实现只提供了标准头文件的一小部分,实际上不提供 C 标准库的实际功能,而是依赖另一方——例如 Linux 系统上的glibc
——来提供 C 标准库的功能。
您所寻求的不仅是在您使用 C90 中没有的 C99/C11/GNU 语言 功能时发出警告,而且在您使用 库 时发出警告> C90 本身未定义的功能。可悲的是,由于上述原因,单独的编译器无法做到这一点——它与libc
的使用方式无关。在glibc
系统上,C 标准库将选择-std=c90
或-ansi
定义的宏:
使用
-ansi
选项时预定义宏__STRICT_ANSI__
。一些头文件可能会注意到这个宏,并避免声明某些函数或定义 ISO 标准不要求的某些宏;这是为了避免干扰任何可能将这些名称用于其他用途的程序。
并通过关闭免费扩展为您提供一些帮助:
如果您使用
‘gcc -ansi’
编译程序,则只能获得 ISO C 库功能,除非您通过定义一个或多个功能宏来明确请求其他功能。
但是,这仅涵盖扩展和 POSIX-but-not-ISO C 函数;如果在 ISO C 和 POSIX.1 中以不同方式指定函数的行为,它不会拯救您!
【讨论】:
以上是关于严格的 C90 代码的 GCC 选项?的主要内容,如果未能解决你的问题,请参考以下文章