当前位置:首页 > > 小麦大叔
[导读]这个是今天在微信群里讨论的一个问题,然后我们就在群里讨论,有的大神说这个是内存越界,也有大神说可能是人品有问题,也有大神说这个是因为写代码前没有选好一个良辰吉日,反正大家想法都非常多,也非常古怪,这可能就是讨论群存在的一个原因了。经过不断的验证,发现这个问题是因为编译器优化的问题。


这个是今天在微信群里讨论的一个问题,先看图片

点击查看大图

代码流程大概是这个样子的

点击查看大图

查看 lengthspace1 的值,明显看到 length 小于 space1 的值,即使是这样小白都能搞懂流程的情况下,代码还是跑到else里面区执行

调试查看数据

然后 我们就在群里讨论,有的大神说这个是内存越界,也有大神说可能是人品有问题,也有大神说这个是因为写代码前没有选好一个良辰吉日,反正大家想法都非常多,也非常古怪,这可能就是讨论群存在的一个原因了。

经过不断的验证,发现这个问题是因为编译器优化的问题

如果在设置里面把优化选项去掉代码就执行正确

编译器对代码优化

当然还有一个问题,就是如果我想开启优化,毕竟代码太大占用的存储空间是很大的,如果能节省点空间是最好的了。所以就出现了一种,只针对某些代码不优化的设置

像这样


我们使用GCC编译的时候,也是有可能因为代码优化导致这样的问题的,庆幸的是,GCC也有设置不进行优化的开关。


#使用GCC编译器设置选择性不优化某段代码

#pragma GCC push_options
#pragma GCC optimize ("O0")
#pragma GCC pop_options

push 的意思是把当前的编译优化选项压栈,然后再设置当前的优化选项,之后再出栈,把之前压栈的选项提取出来。

具体可以参考链接:

https://gcc.gnu.org/onlinedocs/gcc-4.4.2/gcc/Function-Specific-Option-Pragmas.html

链接里面还介绍了一些其他的用法,原文如下

5.52.12 Function Specific Option Pragmas
#pragma GCC target ("string"...)
This pragma allows you to set target specific options for functions defined later in the source file. One or more strings can be specified. Each function that is defined after this point will be as if attribute((target("STRING"))) was specified for that function. The parenthesis around the options is optional. See Function Attributes, for more information about the target attribute and the attribute syntax.
The `#pragma GCC target' pragma is not implemented in GCC versions earlier than 4.4, and is currently only implemented for the 386 and x86_64 backends.

#pragma GCC optimize ("string"...)
This pragma allows you to set global optimization options for functions defined later in the source file. One or more strings can be specified. Each function that is defined after this point will be as if attribute((optimize("STRING"))) was specified for that function. The parenthesis around the options is optional. See Function Attributes, for more information about the optimize attribute and the attribute syntax.
The `#pragma GCC optimize' pragma is not implemented in GCC versions earlier than 4.4.

#pragma GCC push_options
#pragma GCC pop_options
These pragmas maintain a stack of the current target and optimization options. It is intended for include files where you temporarily want to switch to using a different `#pragma GCC target' or `#pragma GCC optimize' and then to pop back to the previous options.
The `#pragma GCC push_options' and `#pragma GCC pop_options' pragmas are not implemented in GCC versions earlier than 4.4.

#pragma GCC reset_options
This pragma clears the current #pragma GCC target and #pragma GCC optimize to use the default switches as specified on the command line.
The `#pragma GCC reset_options' pragma is not implemented in GCC versions earlier than 4.4.

#当然还有指定某个函数设置优化等级

int max(int a, int b) __attribute__((optimize("O0")));
{
 return a < b ? a : b;
}

#使用volatile 关键字避免编译器优化

volatile 的作用是提醒CPU,如果遇到被volatile 修饰的变量,要从内存里面去取值,而不要偷懒,直接从缓存里面取值,我们一般是用在那些被中断处理函数使用的那些变量。

如果有些代码,你不希望CPU偷懒,那你就可以加上volatile ,让CPU从内存取数据。

CSDN上有这样一个例子

https://blog.csdn.net/qq_28637193/article/details/88988951今天碰到一个gcc优化相关的问题,为了让一个页变成脏页(页表中dirty位被置上),需要执行下面这段代码:

1 uint32_t *page;
2 // ...
3 page[0] = page[0];
最后一行代码很有可能被gcc优化掉,因为这段代码看起来没有任何实际的作用。那么如何防止gcc对这段代码做优化呢?

设置gcc编译时优化级别为-O0肯定是不合适的,这样对程序性能影响会比较大。stackoverflow上的Dietrich Epp给出了一个强制类型转换的方案:

((unsigned char volatile *)page)[0] = page[0];
通过volatile关键字禁止gcc的优化


#总结、什么情况会导致这样的问题?

1、堆栈溢出应该是一个原因,之前我有遇到的情况是栈空间设置太小,然后溢出到堆空间导致问题。


2、使用某个函数导致溢出,我们使用的函数,比如,内存拷贝函数,如果长度设置不对,也会导致影响到其他的代码。


3、还有就是上面说的编译器优化导致的问题。


—— The End —

推荐好文   点击蓝色字体即可跳转
 感觉身体被掏空!只因为肝了这篇空间矢量控制算法
 当心!别再被大小端的问题坑了
 PID微分器与滤波器的爱恨情仇
 简易PID算法的快速扫盲
 增量式PID到底是什么?
 三面大疆惨败,因为不懂PID的积分抗饱和

原创不易,欢迎转发、留言、点赞、分享给你的朋友,感谢您的支持!


长按识别二维码关注获取更多内容


免责声明:本文内容由21ic获得授权后发布,版权归原作者所有,本平台仅提供信息存储服务。文章仅代表作者个人观点,不代表本平台立场,如有问题,请联系我们,谢谢!

本站声明: 本文章由作者或相关机构授权发布,目的在于传递更多信息,并不代表本站赞同其观点,本站亦不保证或承诺内容真实性等。需要转载请联系该专栏作者,如若文章内容侵犯您的权益,请及时联系本站删除。
换一批
延伸阅读

LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: 驱动电源

在工业自动化蓬勃发展的当下,工业电机作为核心动力设备,其驱动电源的性能直接关系到整个系统的稳定性和可靠性。其中,反电动势抑制与过流保护是驱动电源设计中至关重要的两个环节,集成化方案的设计成为提升电机驱动性能的关键。

关键字: 工业电机 驱动电源

LED 驱动电源作为 LED 照明系统的 “心脏”,其稳定性直接决定了整个照明设备的使用寿命。然而,在实际应用中,LED 驱动电源易损坏的问题却十分常见,不仅增加了维护成本,还影响了用户体验。要解决这一问题,需从设计、生...

关键字: 驱动电源 照明系统 散热

根据LED驱动电源的公式,电感内电流波动大小和电感值成反比,输出纹波和输出电容值成反比。所以加大电感值和输出电容值可以减小纹波。

关键字: LED 设计 驱动电源

电动汽车(EV)作为新能源汽车的重要代表,正逐渐成为全球汽车产业的重要发展方向。电动汽车的核心技术之一是电机驱动控制系统,而绝缘栅双极型晶体管(IGBT)作为电机驱动系统中的关键元件,其性能直接影响到电动汽车的动力性能和...

关键字: 电动汽车 新能源 驱动电源

在现代城市建设中,街道及停车场照明作为基础设施的重要组成部分,其质量和效率直接关系到城市的公共安全、居民生活质量和能源利用效率。随着科技的进步,高亮度白光发光二极管(LED)因其独特的优势逐渐取代传统光源,成为大功率区域...

关键字: 发光二极管 驱动电源 LED

LED通用照明设计工程师会遇到许多挑战,如功率密度、功率因数校正(PFC)、空间受限和可靠性等。

关键字: LED 驱动电源 功率因数校正

在LED照明技术日益普及的今天,LED驱动电源的电磁干扰(EMI)问题成为了一个不可忽视的挑战。电磁干扰不仅会影响LED灯具的正常工作,还可能对周围电子设备造成不利影响,甚至引发系统故障。因此,采取有效的硬件措施来解决L...

关键字: LED照明技术 电磁干扰 驱动电源

开关电源具有效率高的特性,而且开关电源的变压器体积比串联稳压型电源的要小得多,电源电路比较整洁,整机重量也有所下降,所以,现在的LED驱动电源

关键字: LED 驱动电源 开关电源

LED驱动电源是把电源供应转换为特定的电压电流以驱动LED发光的电压转换器,通常情况下:LED驱动电源的输入包括高压工频交流(即市电)、低压直流、高压直流、低压高频交流(如电子变压器的输出)等。

关键字: LED 隧道灯 驱动电源
关闭