两种 C 语言之间的差异---(GNU C)VS (ANSI C)
GNU C与ANSI C的主要差异在于标准扩展和编译器行为。GNU C在ANSI C基础上增加了大量特有功能,如__attribute__属性、嵌套函数、变长数组等语法扩展,默认采用-std=gnu17模式。而ANSI C严格遵循ISO标准(如C99/C11),强调可移植性。GNU C更适合Linux开发,但会降低代码可移植性。如需跨平台,建议使用gcc -std=c11 -pedantic强制A

对于软件工程师来说,尤其是嵌入式开发,C 语言可以说是最最最主要的编程语言,然而,Linux GNU C 和 ANSI C 这两者之间,却存在着一定的差异,一旦使用不当,很容易造成语法错误。Linux 上可用的 C 编译器是 GNU C 编译器,它建立在自由软件基金会的编程许可证的基础上,因此可以自由发布。GNU C对标准C进行一系列扩展,以增强标准C的功能。
下面总结一下之间的差异。GNU C和ANSI C的主要差异体现在以下几个方面:
1、标准遵循程度
- ANSI C:严格遵循ISO C标准(如C89/C90、C99、C11等),强调可移植性和标准一致性。
- GNU C:基于ANSI C标准扩展,添加了大量编译器特有的功能和语法,例如:
- 使用
__attribute__关键字实现特殊属性声明(如内存对齐、弱符号等):int var __attribute__((aligned(16))); - 支持嵌套函数(Nested Functions):
void outer() { int inner() { return 42; } // GNU C扩展 }
- 使用
2、语法扩展
- 内联函数:
- GNU C 使用
__inline__或inline关键字(需结合-std=gnuXX编译选项)。 - ANSI C99 标准后才正式支持
inline。
- GNU C 使用
- 变长数组(VLA):
- GNU C 在C90模式下仍支持VLA(非标准行为):
void func(int n) { int arr[n]; // GNU C扩展 } - ANSI C99 标准才引入VLA。
- GNU C 在C90模式下仍支持VLA(非标准行为):
- 复合字面量(Compound Literals):
int *p = (int[]){1, 2, 3}; // GNU C及C99支持
3、编译器行为
- 默认标准:
- GCC 默认使用
-std=gnu17(GNU C17扩展),而非纯ANSI模式。 - 可通过编译选项强制ANSI模式:
gcc -std=c99 -pedantic # 禁用GNU扩展
- GCC 默认使用
- 未定义行为:
- GNU C 对部分未定义行为(如指针运算)有明确扩展语义。
- ANSI C 严格依赖标准定义。
4、GNU C特有功能
-
语句表达式(Statement Expressions):
int x = ({ int a = 1; a + 2; }); // 返回3 -
类型推导(
typeof):int a = 10; typeof(a) b = 20; // b为int类型 -
零长度数组(Flexible Array Member):
struct S { int len; char data[]; }; // GNU C扩展 -
case范围:
GNU C支持case x…y这样的语法,区间[x,y]中的数都会满足这个case的条件switch (ch) { case '0'... '9': c -= '0'; break; case 'a'... 'f': c -= 'a' - 10; break; case 'A'... 'F': c -= 'A' - 10; break; } -
标号元素
在GNU C中,通过指定索引或结构体成员名,允许 初始化值以任意顺序出现。例如,下面的代码定义了一个数组,并把其中的所有元素赋值为0:unsigned char data[MAX] = { [0 ... MAX-1] = 0 }; -
特殊属性声明
GNU C允许声明函数、变量和类型的特殊属性,以便手动优化代码和定制代码检查的方法# define ATTRIB_NORET __attribute__((noreturn)) .... asmlinkage NORET_TYPE void do_exit(long error_code) ATTRIB_NORET; -
内建函数
GNU C提供了大量内建函数,其中大部分是标准C库函数的GNU C编译器内建版本,例如memcpy()等,它们与对应的标准C库函数功能相同。不属于库函数的其他内建函数的命名通常以__builtin开始,如下所示。#define test_bit(nr,addr) \ (__builtin_constant_p(nr) \ constant_test_bit((nr),(addr)) : \ variable_test_bit((nr),(addr)))
5、标准支持
- ANSI C:需通过编译选项显式启用特定标准(如
-std=c11)。 - GNU C:自动支持最新标准特性,并提供向后兼容的扩展。
6、总结
| 特性 | ANSI C | GNU C |
|---|---|---|
| 标准遵循 | 严格符合ISO C | 标准+扩展 |
| 语法 | 限制性较强 | 支持嵌套函数、语句表达式等 |
| 编译器默认 | 需显式指定(如-std=c99) |
默认启用扩展(-std=gnuXX) |
| 可移植性 | 高 | 依赖GCC环境 |
若需编写可移植代码,建议使用ANSI模式编译:
gcc -std=c11 -pedantic -Wall

更多推荐



所有评论(0)