关于Keil编译器使用C90的说明及如何切换成C99规则

前言

前几天打开keil编译器编译了一个代码,提示我的一个变量没有定义,我写了如下的代码:
int ret = loop_task();提示我的ret没有定义,后面仔细研究了一下发现是keil编译器默认的编译规则问题,keil默认使用C90的规则,所有变量在使用前就已经定义完成,这样可以提升编译器的编译效率,随用随定义的规则是C99引入的,代码灵活,但是编译效率不如C90规则下的,但是就习惯性来说,C99下的规则更符合代码编写逻辑,大部分工程师开发的代码都是基于C99规则下的,如果C90规则不习惯,我们可以修改KEIL的默认编译规则为C99下的。

原因分析

1. C90 标准限制

Keil 默认使用的 C90 标准(ANSI C 1990) 要求:
变量必须在代码块({})的开头声明,不能在中间定义变量。
这样可以让编译器在编译时提前知道所有变量,提高编译效率。
C99 标准(ANSI C 1999) 允许变量在任意位置声明,但 Keil 默认不支持该特性。

2. Keil 编译器(如 armcc 或 C51)默认遵循 C90

例如在 Keil C51(用于 8051)或 Keil MDK-ARM(用于 STM32)中,默认编译器是 armcc,它默认遵循 C90。
在 C90 规则下,下面的代码会报错:
c

int main() {
    int a = 10;
    a = a + 1;  // ✅ 正确,变量已提前声明
    
    int b = a + 5;  // ❌ 错误!C90 不允许在中间定义变量
    return 0;
}

正确写法(C90 兼容):

int main() {
    int a = 10;
    int b;  // 变量必须在代码块开头声明
    a = a + 1;
    b = a + 5;  // ✅ 这样就符合 C90 规范
    return 0;
}

解决方案:启用 C99 支持

如果想在 Keil 中使用 边定义边使用,可以尝试开启 C99 或更新标准:

Keil MDK-ARM(ARM 编译器):

在 Keil uVision 中,进入 Project -> Options for Target -> C/C++ 选项卡。
找到 Language Standard,选择 C99 Mode 或 gnu99 Mode。
Keil C51(8051 编译器):

由于 Keil C51 仍然基于旧版 C 标准,不支持 C99,需要手动调整代码结构,先声明变量再使用。

C90和C99区别

在Keil中使用 C90 和 C99 编译标准时,编译效率的区别主要体现在 代码结构、内存管理、编译器优化 以及 语言特性 上。我们可以从多个角度来分析这两者的编译效率差异。

特性C90C99
变量声明位置必须在函数体开始时声明所有变量允许在函数体中的任意位置声明变量
内联函数不支持内联函数支持 inline 关键字用于声明内联函数
布尔类型没有 bool 类型,通常用 int 模拟支持 bool 类型,定义在 <stdbool.h> 头文件中
复合字面量不支持复合字面量支持复合字面量,如 {1, 2, 3}
变长数组(VLA )不支持变长数组支持变长数组,数组的大小可以在运行时动态决定
单一声明不允许单一声明多个变量支持单一声明多个变量
结构体类型的限定符结构体成员必须单独声明支持结构体成员的类型限定符(例如 const)
限制符对于 long long 类型的支持有限long long 类型得到正式支持,表示 64 位整数
函数声明方式函数声明必须在函数定义之前允许函数声明后定义(或直接在同一个文件中定义)
支持的库功能不支持动态分配的内存和部分标准库功能引入了 <stdbool.h>、<tgmath.h>、<inttypes.h> 等
宏定义常量宏常量和常量表达式需通过 #define 定义宏常量和常量表达式支持 const 或 enum 作为替代
宽字符类型没有 wchar_t 和 wchar 类型支持 wchar_t 类型(用于宽字符)
条件编译#if 和 #ifdef 仅支持常量表达式支持 #if 和 #ifdef 以及常量表达式和 sizeof
类型限定符不支持 restrict 关键字支持 restrict 关键字,优化指针别名消除
指针算术的范围检查不做严格检查对指针算术进行了更严格的范围检查
变量初始化需要在数组或结构体中逐项赋值支持结构体和数组的 指定初始化,即可以不按照顺序赋值
编译选项对编译器的要求相对简单,兼容老旧编译器编译器对 C99 特性有更高要求,需要支持 C99 模式

注意:

如果基于C90规则开发的代码在C99编译器中是可以正常编译的,但是如果基于C99规则开发的代码,在C90编译器中是不支持的,可能会有特性不支持造成错误

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值