通过反汇编来理解restrict关键字

一次难忘的面试经历

多年前,一次互联网某厂实习生的面试题,题目的代码片段很简单,如下:

 1  #include 2  int main()3 {4      int *restrict pInt = (int*)malloc(4);5      int *pNewInt = pInt;6      return 0;7 }
12345678

面试官问我运行结果是什么,我居然当时不加思索的回答,编译器会报错。当时个人理解是这样的,首先用malloc函数分配了一个4Bytes大小的内存,并让pInt指针指向它。同时pInt指针,也被restrict关键字修饰。而restrict就是用来表明是访问一个数据对象的唯一且初始的方式。因此在第5行中,将pInt的值赋值给了另一个指针pNewInt就是错误的。但是遗憾的是,这种错误编译器是不会报错的。下面我们就这个问题来聊一聊restrict关键字。

不使用restrict关键字

restrict关键字实际上在C99标准出来以前,编译器就已经开始支持类似restrict的语句了,如编译器定义了__restrict。restrict关键字,实际上是用来指示编译器对代码进行优化的。在分析具体含义以前,我们先来看一个没有用restrict的例子。

在main函数中定义了三个参数p、q、r。这之后调用了f函数,并把p和q的地址传递进去。在f中根据这两个地址,将p和q分别设置为2和3,最后把p的值2当做函数返回值返回,并赋值给整形变量r。这个代码很简单,不过重点不是看它,而是它的反汇编代码,下面我们通过objdump工具执行objdump -j .text -l -C -S test来生成汇编代码。 首先来看下main函数的汇编代码。如下图所示

在反汇编代码中的可以看到,分别将p和q的地址分别赋值给了rdi和 rsi寄存器。即rdi保存了p的地址,rsi保存了q的地址。之后调用了f函数。而在f函数的反汇编代码中,通过如下图所示能确认rdi确实保存着p的地址

 接着,如下图所示,可以看到通过调用了puts函数向屏幕打印信息

最后,f函数最后用rax所指向区域的值,赋给了eax寄存器,即将p的值放入eax作为返回值返回。

好了,现在有一个疑问,代码其对应的反汇编代码干嘛不直接把立即数2直接赋值给eax,反而多此一举从rax所指向的内存中把2取出来给eax呢?因为编译器之所以不直接把2赋值给eax,而非要从内存中获取,就是担心代码中会通过其他指针访问p所占的区域。在test.c的代码中我们通过指针a访问了p所占的区域,但是编译器不知道指针b是否也是指向p所占的区域,通过指针b是否也对该区域做了修改。因此编译器只能根据return *a,从内存中将2取出来赋值给eax。

使用restrict关键字

好了,怎么样才能让编译器变得聪明一点呢?这个时候restrict就派上用场了。修改上面代码

 运行编译命令gcc -g -O2 -std=c99 -o test test.c进行编译,使用反汇编工具objdump查看发现

可以看到直接把2赋给了eax寄存器,作为f的返回值返回了。看明白了吧,restrict关键字起作用了,编译器检测到指针a和b都使用了restrict关键字,也就是说,它们所指向的空间都只能通过指针a和b访问,不会有其他途径。这个时候,编译器就可以放心大胆地进行优化了,直接把2赋给了eax,而不用再从内存中获取了。这样,f的执行效率也提高了。这里还有一点需要注意,C 程序并不支持restrict关键字,但是可以使用“__restrict”关键字。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/339118.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

python车牌识别系统开源代码_汽车牌照识别系统【YOLO+MLP】

车牌识别系统可以自动检测并识别图像中的车辆牌照,其算法主要包括牌照定位、牌照分割、字符识别等步骤。本文将给出一种基于深度学习的车牌识别系统方案。要快速掌握开发人工智能系统的技能,推荐汇智网的 机器学习系列在线课程由于可以自动地从视频图像中…

js text 和 html,JS DOM innerText和textContent的区别

innerText和textContent很多人会困惑,因为都可以用来获取文本内容,实际上,两者还是有很多区别的,本文就将介绍这两个属性的异同,希望可以对大家的学习有所帮助。一、之前错误的认识innerText IE6就开始支持&#xff0c…

如何用耳机翻页_游戏耳机的经典之作—罗技(G)Astro A40体验

前言经常去网吧玩游戏的朋友,在家玩如果没有头戴式耳机,那体验真的会差一大截。优秀的电竞游戏耳机会带来更好的游戏体验,不仅是舒适性。像绝地求生这类FPS游戏,游戏耳机会让听声辩位更容易更精确。最近因为大促降价入手的罗技&am…

我改了500个Bug,但是!!

IT程序猿 微博网友评论:空白一页blank:不写bug怎么改bug 抠Bee:不经意间病毒都出来了我在海的这边你在哪里丫:好了,发给开发小弟了富贵小小神仙:要不然呢,那些从开发到维护的程序员不都是靠这么…

globalmapper如何选取图像上的点_OpenCV 进阶应用,用编程手段搞定图像处理

在我们生活中,常见的图像处理软件有Adobe Photoshop、Adobe Illustrator等。然而,并非只有软件才能实现图像处理,通过编程手段也是能实现的!通过编程手段实现图像处理,也就是计算机视觉。所谓计算机视觉,就…

pytorch relu函数实现_什么是pytorch?

PyTorch是一个:机器学习框架,简单易学可以看做是支持GPU计算和自动微分计算的“Numpy”库支持100多种Tensor常规算子,包括:创建、索引、切片、转置、连接、随机数、形状改变,线性代数、数学计算Tensor是一个有值有属性…

C sort 排序函数用法

最近在刷ACM经常用到排序,以前老是写冒泡,可把冒泡带到OJ里后发现经常超时,所以本想用快排,可是很多学长推荐用sort函数,因为自己写的快排写不好真的没有sort快,所以毅然决然选择sort函数用法1、sort函数可…

python人脸_Python 使用 face_recognition 人脸识别

Python 使用 face_recognition 人脸识别 人脸识别 face_recognition 是世界上最简单的人脸识别库。 使用 dlib 最先进的人脸识别功能构建建立深度学习,该模型准确率在99.38%。 Python模块的使用 Python可以安装导入 face_recognition 模块轻松操作,对于简…

C语言,一把菜刀。

C 与 C 的真正区别在哪里?C是中餐厨师的菜刀,做啥菜就那一把刀,切菜切肉切鱼,都是这一把刀,刀工好的师傅,豆腐都能切成一朵花。无论你提什么概念,都能用指针给你做出来,如果不行&…

css中设置br标签之后的样式_CSS学习

语法:选择器,声明(由一个属性和一个值)注释:/* */选择器:1. id选择器,class选择器2. 组和选择3. 属性选择创建:外部样式表html <head> <link rel"stylesheet" type"text/css" href"mystyle.css"> </head>内部样式表html <h…

eclipse扩展点_Eclipse扩展点评估变得容易

eclipse扩展点编码Eclipse扩展点评估有点冗长&#xff0c;而且很少能自我解释。 当我最近忙于自己忙于这个话题时&#xff0c;我写了一个小助手&#xff0c;目的是减少通用编程步骤的样板代码&#xff0c;同时增加开发指导和可读性。 它原来是不容易找到一个表现的解决方案&am…

google账号解除游戏绑定_附方法!关于物联卡手机号的绑定与解绑

我们在使用物联卡时第一步都知道绑定手机号&#xff0c;只有绑定了手机号我们才能进行正常的充值、续费、查询等日常操作&#xff0c;当我们不再使用这些物联卡时&#xff0c;你知道怎么解绑吗&#xff1f;今天&#xff0c;我们以中国移动物联卡为例&#xff0c;咱们来看一下移…

elasticsearch原理_花几分钟看一下Elasticsearch原理解析与性能调优

基本概念定义一个分布式的实时文档存储&#xff0c;每个字段 可以被索引与搜索一个分布式实时分析搜索引擎能胜任上百个服务节点的扩展&#xff0c;并支持 PB 级别的结构化或者非结构化数据用途全文检索结构化搜索分析VS传统数据库传统数据库提供精确匹配ES提供精确匹配全文检索…

spark wai_WAI-ARIA对自动完成小部件的支持

spark wai在这篇文章中&#xff0c;我想讨论一个AutoComplete小部件的可访问性。 在您键入该字段时&#xff0c;通常会使用“自动完成”窗口小部件提供建议。 在当前的工作中&#xff0c;我基于Twitter的Typeahead &#xff08;一个灵活JavaScript库&#xff09;实现了JSF组件&…

快速学习C语言的途径,让你少走弯路!

1标准C语言能干什么&#xff1f;坦白讲&#xff0c;在今天软件已经发展了半个多世纪&#xff0c;单纯的C语言什么都干不了。标准C语言库只提供了一些通用的逻辑运算方法以及字符串处理&#xff0c;当然字符串在C语言看来也是一种操作内存的方法&#xff0c;所以单纯的C什么都做…

计算机基础教育学,计算机基础教育教学改革与创新

计算机基础教育教学改革与创新伴随《国家中长期教育改革和发展规划纲要(2010-2020)》的颁布,我国计算机基础教育进入一个新的发展阶段,对计算机基础教育"面向应用、能力导向、注重素质"指导思想的深入研究和实践是深化计算机基础教育教学改革的切入点。下面是小编搜集…

C语言学习趣事_你不知道的C语言应用

一、引我一直不明白“文人相轻”是什么意思&#xff0c;也许就是说&#xff1a;文人清客之间互相瞧不起的事情吧。但对于我来说&#xff0c;文人相轻就是表示&#xff1a;无知者无畏。无论你的某一方面的语言学的怎么样&#xff0c;怎么样的牛逼&#xff0c;你可以眼光狭窄&…

html打开显示脚本错误,IE浏览器显示脚本错误怎么解决?IE浏览器脚本错误解决方法图文教程介绍...

只要一打开网页&#xff0c;就会弹出一个“当前页面的脚本发生错误”提示框&#xff0c;如下图&#xff0c;不论按“是”或者“否”&#xff0c;当打开其它网页时&#xff0c;又会弹出一个这样的“脚本错误”提示框&#xff0c;这样的问题该如何解决呢。出现这样的情况&#xf…

jenkins 新手入门安装失败_树莓派安装jenkins,安安静静做个持续集成打包机

对于java程序来说&#xff0c;手动发布服务端是耗时和无聊的&#xff0c;jenkins很好地解决了这个问题&#xff0c;闲着也是闲着就在树莓派上装个jenkins帮我们打包发布吧。这次我们需要安装三个软件&#xff1a;jdk&#xff1a;编辑java程序必要的。maven&#xff1a;maven结构…

java开发C编译器:结构体的解析和执行

用java开发C语言编译器结构体是C语言中&#xff0c;最为复杂的原生数据结构&#xff0c;它把多种原生结构结合在一起&#xff0c;形成一个有特点含义的数据结构&#xff0c;要实现一个完整的C语言编译器或解释器&#xff0c;就必须要拥有对结构体的解析能力&#xff0c;本节&am…