<p>GCC默认使用-std=gnu11(C11加GNU扩展),可通过gcc -E -dM - </dev/null | grep __STDC_VERSION__查看:输出201112L对应C11,199901L为C99,无输出或199001L则为C89;-std=c11严格遵循ISO标准,-std=gnu11允许GNU扩展。</p>

直接用 -std= 加标准代号,比如 -std=c11 或 -std=gnu99,就能指定 C 语言标准;C++ 同理,用 -std=c++17 这类。
怎么查 GCC 默认用哪个 C 标准
不加 -std 时,GCC 实际默认用的是 -std=gnu11(C11 + GNU 扩展),不是纯 C11。验证方法很简单:
gcc -E -dM - </dev/null | grep __STDC_VERSION__
输出 #define __STDC_VERSION__ 201112L 就说明默认支持 C11;如果是 199901L,那就是 C99。
- 没输出或输出
199001L,基本是 C89/C90 模式 - 这个值只反映预处理器能识别的版本,不代表编译器实际启用的模式(
-std才决定行为) - 别依赖
__STDC_VERSION__判断是否启用了某特性,它只是宏定义,真正起作用的是-std参数
-std=c11 和 -std=gnu11 有啥区别
关键在「是否允许 GNU 扩展」:
-
-std=c11:严格遵循 ISO C11 标准,禁用所有 GNU 特性(比如内联函数的非标准写法、typeof、语句表达式({...})) -
-std=gnu11:C11 标准 + GCC 自己加的扩展,兼容性更好,日常开发更常用 - 用
-std=c11编译含typeof(x)的代码会报错;-std=gnu11就能过 - 如果你要写可移植代码(比如发到其他编译器如 clang 或 MSVC),优先选
-std=c11或-std=c17
常见错误:for 循环里定义变量报错
典型报错:error: ‘for’ loop initial declarations are only allowed in C99 or C11 mode
- 这是 C89/C90 不允许的语法,但
int i = 0写在for里很常见 - 解决办法不是改代码,而是加
-std=c99或更高(-std=c11、-std=gnu99都行) -
-std=c89和-std=ansi等价,都强制走最老的标准,慎用 - 注意:即使源文件是
.c后缀,GCC 也不会自动按 C99 编译,必须显式指定
C++ 的 -std 参数写法和陷阱
C++ 标准参数命名规则统一,但容易漏掉 ++ 符号:
- 正确:
-std=c++11、-std=c++14、-std=c++17、-std=c++20 - 错误:
-std=c11(这是 C 标准)、-std=cpp11(无效)、-std=C++11(大小写敏感,必须小写) -
-std=gnu++17类似 C 的 gnu 变体,允许 GNU 扩展 + C++17 特性 - 某些旧版 GCC(如 4.8)不支持
c++14,会提示unrecognized command line option,得换编译器或降级标准
最容易被忽略的是:标准选项必须写在源文件名之前,gcc main.c -std=c11 是无效的,GCC 会把它当成对 main.c 的文件名处理,而不是编译选项——顺序错了就白加。


















