neutronlmk 发表于 2021-6-24 18:43:07

加了volatile修饰的变量,仍被编译器优化掉

代码如下:
/*
* 函数说明:RF 发射模式
* 全局变量:无
* 输入参数:无
* 返回数据:无
* 注:
*/
void RF_TxMode(void)
{
    volatile uint8_t u8a_Data;

    RF_ReadBuffer(RF_CFG_TOP, u8a_Data, 2);
    u8a_Data &= ~RX_ON;
    RF_WriteBuffer(W_REGISTER | RF_CFG_TOP, u8a_Data, 2);
}

是不是临时变量不能用volatile修饰?
要u8a_Data不被修改,怎么处理?

mangolu 发表于 2021-6-24 18:46:50

昨时变量要初始化,否则值为不定。

neutronlmk 发表于 2021-6-24 18:51:10

mangolu 发表于 2021-6-24 18:46
昨时变量要初始化,否则值为不定。

即是不必要加volatile,只要使用前初始化即可?

SUPER_CRJ 发表于 2021-6-24 19:04:43

static 了解一下

chunjiu 发表于 2021-6-24 19:13:21

局部变量在堆栈上,退出函数就没了,你的修饰是废的。

tang_qianfeng 发表于 2021-6-24 19:30:54

volatile是修饰的io,就是对数组的读写不缓存,总是对地址操作

GZZXB 发表于 2021-6-24 19:32:36

怎么个优化掉了?8a_Data在函数体内不可见吗?

lhj200304 发表于 2021-6-24 19:40:11

局部变量再堆栈上,退出后就没有了,你可以用static 修饰或者变成全局变量。就可以了

GZZXB 发表于 2021-6-24 19:41:42

重看了下楼主描述u8a_Data应该可见,volatile是肯定起作用的。如果函数体内变量值被莫名修改。提两点认为存在的可能性,第一楼主有没有跑ble wifi之类的代码?第二会不会是被其它函数抢占同时该函数分配的内存恰好共用了u8a_Data的地址?

GZZXB 发表于 2021-6-24 19:44:27

chunjiu 发表于 2021-6-24 19:13
局部变量在堆栈上,退出函数就没了,你的修饰是废的。

   这个楼主应该知道,我猜他描述的优化应该是在函数体内被优化。

shuiluo2 发表于 2021-6-24 20:33:06

改用全局变量吧,全局变量更好使

ddplys 发表于 2021-6-24 20:41:15

使用static

jianfengxixi 发表于 2021-6-24 20:57:19

改全局数组。

lusson 发表于 2021-6-24 21:23:46

使用全局变量就好了。
局部变量static不太推荐,我们的内部编码规范里是不允许的。

neutronlmk 发表于 2021-6-24 22:08:22

GZZXB 发表于 2021-6-24 19:44
这个楼主应该知道,我猜他描述的优化应该是在函数体内被优化。

是的。函数体内被优化了导致不是我想要的结果。

neutronlmk 发表于 2021-6-24 22:10:29

lusson 发表于 2021-6-24 21:23
使用全局变量就好了。
局部变量static不太推荐,我们的内部编码规范里是不允许的。 ...

正在改全局变量!
不建议局部变量 static是什么原因,我不是有用到,我觉得如此封装的子程序好看。

bad_fpga 发表于 2021-6-24 22:57:35

lusson 发表于 2021-6-24 21:23
使用全局变量就好了。
局部变量static不太推荐,我们的内部编码规范里是不允许的。 ...

也请教一下,为啥 不建议局部变量用static呢

lusson 发表于 2021-6-24 23:08:48

neutronlmk 发表于 2021-6-24 22:10
正在改全局变量!
不建议局部变量 static是什么原因,我不是有用到,我觉得如此封装的子程序好看。 ...

不建议使用的原因是变量不方便统一管理,容易发生莫名其妙的问题,而且静态局部变量初始化也是一个问题,只能在定义的时候初始化,不方便统一初始化。

GZZXB 发表于 2021-6-24 23:17:48

lusson 发表于 2021-6-24 21:23
使用全局变量就好了。
局部变量static不太推荐,我们的内部编码规范里是不允许的。 ...

   全局变量满天飞似乎也不太好。

neutronlmk 发表于 2021-6-25 07:06:13

GZZXB 发表于 2021-6-24 23:17
全局变量满天飞似乎也不太好。

我定下的规范仍建议使用全局变量——还在用1k rom的otp,使用指针代码轻易大0.25k。

neutronlmk 发表于 2021-6-25 07:21:52

lusson 发表于 2021-6-24 23:08
不建议使用的原因是变量不方便统一管理,容易发生莫名其妙的问题,而且静态局部变量初始化也是一个问题, ...

感谢指教。

tang_qianfeng 发表于 2021-6-25 07:51:44

lusson 发表于 2021-6-24 23:08
不建议使用的原因是变量不方便统一管理,容易发生莫名其妙的问题,而且静态局部变量初始化也是一个问题, ...

为何局部静态变量只能定义时初始化?

lusson 发表于 2021-6-25 09:42:18

tang_qianfeng 发表于 2021-6-25 07:51
为何局部静态变量只能定义时初始化?

局部静态变量作用域只是在函数内,你没办法显式的在上电的时候使用init函数去初始化他,只在定义的时候比如static uint8_t xxx=5来初始化。

lusson 发表于 2021-6-25 09:43:25

GZZXB 发表于 2021-6-24 23:17
全局变量满天飞似乎也不太好。

全局变量一般只限定在某个模块内部,模块之间交互使用接口。

ycheng2004 发表于 2021-6-25 10:23:56

tang_qianfeng 发表于 2021-6-24 19:30
volatile是修饰的io,就是对数组的读写不缓存,总是对地址操作

+1



            

nanfang2000 发表于 2021-6-25 10:30:42

一定是楼主自己弄错了,从code逻辑来看,既不需要volatile也不需要static,你的一楼代码看起来是能工作的。
“仍被编译器优化掉”你怎么得出这个结论?
通过调试器看到的不一定是真的,特别是开了优化的情况下。建议调试的时候不要开任何编译优化

cloudboy 发表于 2021-6-25 10:32:14

上面的解决方案怎么都是改全局变量、static什么的?都不是根本问题
楼主把汇编出来的代码贴上来和具体的现象分析一下,如果没有产生实际操作指令,那就是编译器问题!
如果有的话,那就要看是否存在mmu、cache、dma、内存屏障等方向上去查

vuo50z 发表于 2021-6-25 10:35:07

楼主都没表达清楚问题,就出了这么多回答,我也是服了

cloudboy 发表于 2021-6-25 10:35:08

nanfang2000 发表于 2021-6-25 10:30
一定是楼主自己弄错了,从code逻辑来看,既不需要volatile也不需要static,你的一楼代码看起来是能工作的。 ...

和你的看法一致,上面的代码压根不用volatile,这里用volatile只会多增加指令拖慢速度

knight_sh 发表于 2021-6-25 11:03:35

楼主先去看下书,复习下变量的作用域,然后再弄清楚volatile到底是怎么回事

knight_sh 发表于 2021-6-25 11:06:43

lusson 发表于 2021-6-24 21:23
使用全局变量就好了。
局部变量static不太推荐,我们的内部编码规范里是不允许的。 ...

一般内部staic变量的函数肯定不是可重入的,外部调用不清楚这个细节容易出问题

knight_sh 发表于 2021-6-25 11:10:10

vuo50z 发表于 2021-6-25 10:35
楼主都没表达清楚问题,就出了这么多回答,我也是服了

哈哈,是的,lz问题可能没定位清楚,就让变量背锅
不过坛友出于热情帮忙分析可能的问题点吧

norman33 发表于 2021-6-25 13:36:19

局部变量不赋初始值,这个问题很初级哎

albert_w 发表于 2021-6-25 15:04:55

lz都还没问明白咋大家答案都明明白白了…

zchong 发表于 2021-6-25 15:25:50

疑问中…,楼主到底是啥问题?大家讨论的这么热烈,都是半仙?

armok. 发表于 2021-7-30 19:47:12

因为举报该帖子被自动屏蔽和移走。
原论坛:51单片机

armok. 发表于 2021-8-9 22:40:10

帖子移动通知:
原分论坛:举报自动屏蔽区
目标分论坛:51单片机
移动时间:0小时之后
页: [1]
查看完整版本: 加了volatile修饰的变量,仍被编译器优化掉