背景

今天面试了一家公司,面试官问了我一个开放性的问题。大致意思是,为什么对volatile修饰的变量调用memset函数,编译的时候会报错。当然,我是不知道为什么啦。之前没有遇到过嘛。不过我还是做了一点分析,我认为问题出在memset函数的实现上。一般情况下volatile关键字修饰的变量在编译的时候会取消编译优化,即每次使用变量时都会访问变量对应的地址,而不是将变量读入寄存器中连续使用。

探索

面试结束后,我写了个简单的代码测试了一下。大致如下

#include <stdio.h>
int main(void)
{
volatile int a;
memset(&a,0,sizeof(int));
}

编译出现了一个警告

warning: passing argument 1 of ‘memset’ discards ‘volatile’ qualifier from pointer target type

我的理解是这个volatile变量传入函数后volatile的特性会被丢掉。

为了研究为什么会这样,接下来我阅读了linux内核中memset的源码。

void *memset(void *pdst, int c, unsigned int plen)
{
/* Now we want the parameters in special registers. Make sure the
compiler does something usable with this. */ register char *return_dst __asm__ ("r10") = pdst;
register int n __asm__ ("r12") = plen;
register int lc __asm__ ("r11") = c; .....
}

上面这部分源码解答了我的疑惑,原来memset在执行过程中,强制把传入的地址放入了r10寄存器,之后也会直接通过连续操作寄存器来访问变量,这里就和volatile每次都要读取物理地址而不能连续使用寄存器内容的特性冲突了。

对volatile修饰的变量使用memset函数的更多相关文章

  1. 【转】C++ const成员变量和成员函数(常成员函数)

    转:http://c.biancheng.net/view/2230.html 在类中,如果你不希望某些数据被修改,可以使用const关键字加以限定.const 可以用来修饰成员变量和成员函数. co ...

  2. C++ const成员变量和成员函数(常成员函数)

    在类中,如果你不希望某些数据被修改,可以使用const关键字加以限定.const 可以用来修饰成员变量和成员函数. const成员变量 const 成员变量的用法和普通 const 变量的用法相似,只 ...

  3. 【Java_多线程并发编程】JUC原子类——原子类中的volatile变量和CAS函数

    JUC中的原子类是依靠volatile变量和Unsafe类中的CAS函数实现的. 1. volatile变量的特性 内存可见性(当一个线程修改volatile变量的值后,另一个线程就可以实时看到此变量 ...

  4. volatile 和const 变量的使用

    一.volatile定义: 一个定义为volatile的变量是说这变量可能会被意想不到的被改变,这样,有了volatile变量后,就提醒编译器就不会去假设这个变量的值了.精确地说就是,编译中的优化器在 ...

  5. Java语言基本语法(一)————关键字&标识符(Java语言标识符命名规范&Java语言的包名、类名、接口名、变量名、函数名、常量名命名规则 )

    一.关键字 关键字的定义和特点 定义:被Java语言赋予特殊含义,用做专门用途的字符串(单词). 特点:关键字中所有字母均为小写 下面列举一些常用的关键字. 用于定义数据类型的关键字:byte.sho ...

  6. volatile修饰符

    Volatile 修饰的成员变量在每次被线程访问时,都强制从共享内存中重新读取该成员变量的值.而且,当成员变量发生变化时,会强制线程将变化值回写到共享内存.这样在任何时刻,两个不同的线程总是看到某个成 ...

  7. memset函数详解

    语言中memset函数详解(2011-11-16 21:11:02)转载▼标签: 杂谈 分类: 工具相关  功 能: 将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值, 块的大 ...

  8. memset函数具体说明

    1.void *memset(void *s,int c,size_t n)总的作用:将已开辟内存空间 s 的首 n 个字节的值设为值 c. 2.样例#include void main(){char ...

  9. C++类中的静态成员变量与静态成员函数

    最近一直看c++相关的项目,但总是会被c++类中的静态成员变量与静态成员函数的理解感觉很是模糊,不明白为什么类中要是用静态成员变量.于是在网上搜集了一些资料,自己再稍微总结下. 静态成员的概念: 静态 ...

  10. 13.C++-静态成员变量、静态成员函数

    首先回顾下成员变量 能通过对象名能够访问public成员变量 每个对象的成员变量都是专属的 成员变量不能在对象之间共享 再来讲讲类的静态成员变量 介绍 静态成员变量属于整个类所有 静态成员变量的生命期 ...

随机推荐

  1. 日志参数 %n 引起的coredump

    今天测试发现一段代码 coredump,居然是一行日志输出.看参数都乱了,以为是内存溢出造成的.查了半天,也没发现问题 最后把前边的函数调用都注释掉,只运行这一段日志输出,依然挂掉 仔细一看: TRA ...

  2. c++中内联函数和宏函数的区别

    一. 区别: 是不是函数: 宏定义不是函数,但是使用起来像函数.预处理器用复制宏代码的方式代替函数的调用,省去了函数压栈退栈过程,提高了效率: 内联函数本质上是一个函数,内联函数一般用于函数体的代码比 ...

  3. linux的打开文件标志O_CLOEXEC

    当没有这个标志,打开文件时,得到的fd, 将会被子进程继承,并且子进程会获得这个fd的读写能力. 往往父进程打开的文件,不希望子进程读写,所以,子进程启动之后,可以手动关闭fd. 但是关闭fd的操作不 ...

  4. Github的.gitignore忽略文件

    Git中有一个非常重要的一个文件-----.gitignore 1.当然如果已经push了怎么办?当然也有解决方法,如下: 有时候在项目开发过程中,突然心血来潮想把某些目录或文件加入忽略规则,按照上述 ...

  5. 【ZYNQ学习】各个主题的值得看的博客

    在学习ZYNQ时会遇到不少问题,这时我们一方面要在DocNav找Xilinx的官方文档,另一方面要参考别人的一些记录的解决好的办法,我在学习的时候看到了不少大佬的博客,给我带来了很大帮助.在这篇博客, ...

  6. 89. 格雷编码 (Medium)

    问题描述 89. 格雷编码 (Medium) n 位格雷码序列 是一个由 2ⁿ 个整数组成的序列,其中: 每个整数都在范围 [0, 2ⁿ - 1] 内(含 0 和 2ⁿ - 1) 第一个整数是 0 一 ...

  7. 项目中pom.xml的某些坐标无法加载

    项目中pom.xml的某些坐标无法加载 maven官方查找对应的坐标文件下载 https://mvnrepository.com/artifact/com.fasterxml.jackson.core ...

  8. mongoengine模型字段非严格校验FieldDoesNotExist

    背景 最近需要从mongoDB中查询数据用于数据分析,一开始就用了pymongo后来发现使用起来很不方便,后面了解到有类似SQLAlchemy的ORM模块mongoengine能够操mongo 简单看 ...

  9. Godot的场景树

    在Godot中,一个游戏的启动大致流程如下: 简而言之,Godot的main启动一个进程,加载所需的驱动设备(如渲染设备:GL/GLES/Vulkan等).音频设备,输入控制器设备等等:然后进入主循环 ...

  10. linux 系统⽇常管理--运维必备

    [监控系统的状态] 1. w 查看当前系统的负载 相信所有的linux管理员最常⽤的命令就是这个'w' 了,该命令显⽰的信息还是蛮丰富 的.第⼀⾏从左⾯开始显⽰的信息依次为:时间,系统运⾏时间,登录⽤ ...