在这里插入图片描述

对于软件工程师来说,尤其是嵌入式开发,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
  • 变长数组(VLA)
    • GNU C 在C90模式下仍支持VLA(非标准行为):
      void func(int n) {
          int arr[n]; // GNU C扩展
      }
      
    • ANSI C99 标准才引入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扩展
      
  • 未定义行为
    • 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

在这里插入图片描述

Logo

这里是“一人公司”的成长家园。我们提供从产品曝光、技术变现到法律财税的全栈内容,并连接云服务、办公空间等稀缺资源,助你专注创造,无忧运营。

更多推荐