0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

const声明的变量一定只能读吗?

鱼鹰谈单片机 来源:鱼鹰谈单片机 2023-10-07 09:23 次阅读

一直以为 const 声明的变量一定是只读的,并且也一定会存放在 FLASH 中,直到在 103 的 map 文件中看到了这个变量:

wKgaomUgsyCAVtmeAACXYb5Ah-M693.jpg

声明如下(函数体外):

wKgZomUgsyGAQHEXAACMSPBygJ0689.jpg

__I 声明如下:

wKgZomUgsyCAWdcnAACXF7CHJh4577.jpg

可以看到,虽然使用 const 修饰变量为只读,但是 MDK 编译器仍将这两个数组放在了 RAM 区(全局变量),这意味着这个变量仍可写(通过指针方式修改),只是不能直接修改而已,还白白浪费了 RAM 空间,因为从实现来看,根本不需要修改这个表,完全可以将其放入 FLASH 空间。

测试发现,是 volatile 这个关键字导致了这个现象,如果没有这个关键字修饰,则能够将其放入 FLASH 中,所以库函数这个代码也是挺迷的。

去除 volatile 修饰后(0x08xx xxxx 为 FLASH 地址区):

wKgZomUgsyGAXxrhAAEUB8_PCNw895.jpg

并且你以为这就完了?当将 const 声明的数组放在函数体中,你会发现这个数组也被放在了 RAM ()区,而不是 FLASH,这样你想节省栈空间的计划就泡汤了。

wKgaomUgsyCAZId8AAFHv4g6qNA355.jpg

那该怎么办?很简单,加一个 static 即可:

wKgZomUgsyCAS6QcAAFJiGOd-Bo615.jpg

但是当你加上 volatile 后,又被放入 RAM 中了,并且这次不是在栈中,而是作为全局变量(map 文件可找)存在,占用了 RAM 的空间。

wKgaomUgsyGAMkmaAAFsNQjA4dM015.jpg

这算不大不小坑吧,望引以为戒!






审核编辑:刘清

声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • FlaSh
    +关注

    关注

    10

    文章

    1633

    浏览量

    147939
  • RAM
    RAM
    +关注

    关注

    8

    文章

    1368

    浏览量

    114640
  • CONST
    +关注

    关注

    0

    文章

    44

    浏览量

    8159

原文标题:坑!const 声明的变量一定只能读吗?

文章出处:【微信号:emOsprey,微信公众号:鱼鹰谈单片机】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    变量声明和定义有什么区别和联系

    变量声明和定义是编程中的两个重要概念,它们在语法和语义上有些区别和联系。在本文中,我将详细介绍变量声明和定义之间的区别和联系。 首先,
    的头像 发表于 12-07 16:14 1118次阅读

    请问如何防止tasking将const变量合并?

    编译中发现tasking将const变量值相同的变量合并了,先去掉些优化选项还是不起作用,只能改变co
    发表于 02-02 08:07

    C语言之正确使用Const

    C语言之正确使用Const基本解释  const个C语言的关键字,它限定变量不允许被改变。使用c
    发表于 10-07 11:20

    C和C++中const的用法比较

    地址,但是应该清楚引用在底层实现上也是通过传递地址的方式来进行的。当不得不为const变量分配空间时,C++仍然能通过一定的手段来尽量进行constant folding。如下代码所示:con
    发表于 11-11 10:00

    C语言——正确使用const

    C语言——正确使用const基本解释   const个C语言的关键字,它限定变量不允许被改变。使用
    发表于 04-23 11:58

    在while循环内添加了个全局变量。然后在当前vi的while循环外读取全局变量只能读

    在while循环内添加了个全局变量。然后在当前vi的while循环外读取全局变量只能读次,为什么啊。全局
    发表于 08-14 15:58

    labview 通过OPC modbus TCP 与施耐德258通讯 字能读能写 但是位只能读不能写

    没问题,我都是确定能读之后再转入写状态。我是按照网上的教程去操作的。用400003.4对应PLC当中的%MX4.4中间变量。更换其他变量后,也是只能读不能写。不知道是怎么回事。有大神知
    发表于 10-20 11:00

    怎么更改const变量PIC18F47K40的值?

    嗨,我需要改变const数组变量的值。我必须声明变量const,因为我需要使用的数组有47
    发表于 03-12 11:36

    Verilog 变量声明与数据类型

    逻辑单元的输出驱动。没有连接驱动的wire型变量的值为高阻’z’。wire类型变量的使用:wire型变量声明与赋值wire类型的变量
    发表于 08-10 14:01

    C语言中变量声明和定义以及extern的用法介绍

    变量声明不同于变量的定义,这点往往容易让人混淆。 l变量声明是告诉编译器,该
    发表于 11-21 10:59 12次下载

    你会使用Linux编程const

    另外const些强大的功能在于它在函数声明中的应用。在个函数声明中,const 可以修饰
    发表于 05-06 16:34 558次阅读
    你会使用Linux编程<b class='flag-5'>const</b>?

    从STM32到CONST的全局变量

       STM32的const全局变量地址 程序如下: const int globalConstDat = 12; int globalDat = 11; int main(void) { int
    的头像 发表于 07-23 10:50 4840次阅读

    怎样去使用C语言中的const关键字呢

    我们会发现两者的区别const个注释的全局变量个注释的局部变量,我们编译都能通过,不过使用全部变量
    的头像 发表于 08-12 09:13 1426次阅读
    怎样去使用C语言中的<b class='flag-5'>const</b>关键字呢

    const 和指针变量使用

    有时候我们希望定义这样变量,它的值不能被改变,在整个作用域中都保持固定。例如,用变量来表示班级的最大人数,或者表示缓冲区的大小。为了满足这
    的头像 发表于 06-22 10:43 477次阅读

    const 声明变量一定是只读的?

    虽然使用 const 修饰变量为只读,但是 MDK 编译器仍将这两个数组放在了 RAM 区(全局变量)。这意味着,这个变量仍可写(通过指针方式修改),只是不能直接修改而已,还白白浪费了
    发表于 10-19 10:05 383次阅读
    <b class='flag-5'>const</b> <b class='flag-5'>声明</b>的<b class='flag-5'>变量</b>不<b class='flag-5'>一定</b>是只读的?