如何让安全用途的memset内存不被优化?volatile指针转换遇警告
解决memset清空缓冲区不被编译器优化的问题
要解决编译器优化掉安全清零操作的问题,有几个靠谱的方案:
用标准安全函数
memset_s(C11及以上标准支持)
这个函数是专门为安全场景设计的,编译器不会优化它的执行。用法很简单:memset_s(buffer, sizeof(buffer), 0, sizeof(buffer));它的参数依次是目标指针、缓冲区大小、填充值、要清零的长度,只要参数合法,就会可靠地完成清零。
自己实现带volatile的清零函数
手动用volatile指针逐字节写入,让编译器无法优化掉这些操作:void secure_memset(void *ptr, int value, size_t len) { volatile unsigned char *p = (volatile unsigned char*)ptr; while (len--) { *p++ = (unsigned char)value; } }调用这个函数代替memset,就能保证缓冲区被实实在在清零,不会被编译器跳过。
给标准memset加内存屏障(平台依赖)
如果一定要用标准memset,可以在调用后加一段空汇编指令,强制编译器刷新内存状态,阻止优化:memset(buffer, 0, sizeof(buffer)); asm volatile("" : : "r"(buffer) : "memory");注意这种方法和编译器、CPU架构有关,通用性不如前两种。
至于你遇到的“volatile指针传给memset报警告”的问题:因为标准memset的参数是void*,不是volatile void*,强制转换会触发类型不匹配警告,而且就算你强转了,memset内部的操作没有volatile限定,编译器还是可能优化掉清零操作,所以这种方法根本不靠谱,别用。
内容的提问来源于stack exchange,提问作者arye
相关产品推荐
相关产品推荐

