浅析 restrict 关键字
一眨眼,入职已经三个月了。感谢同事们的帮助与指导,有幸顺利转正。接下来,就是要好好吃饭,好好码代码,好好写文章了。
今天在阅读 ESP-IDF 的源码时,碰到了一个不太熟悉的特性 restrict
。我只知道它是 C 中的一个关键字(啥?你连看都没看过?哈哈~),它的特性便一无所知了。于是研究一二,记录于此。
碰到一个不熟悉的关键字应该怎么办?当然是查一下 Primer Plus 啦!可是正好手边没有这本书,所以我就百度了一下,下面是百度的信息:
restrict
,C语言中的一种类型限定符(Type Qualifiers),用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。
字面的意思是:该对象只能通过某一指针对其进行操作,除此之外不会对其进行修改。可是,这有什么用呢?再读一遍,我就注意到了一个关键词编译器,看到这三个字我下意识地就想到了编译器优化。那么最直接的方法就是做对比实验了。
首先,写一段常见的测试代码:
#include <stdio.h>int add(int *a, int *b)
{*a = 1;*b = 2;return *a + *b;
}int main(void)
{int sum;int num_1;int num_2;sum = add(&num_1, num_2);printf("The sum is %d.\n", sum);return 0;
}
不用编译运行也知道,输出的结果是 3 。
那么再来看一下 restrict
版本吧:
#include <stdio.h>int add(int *restrict a, int *restrict b) // THIS LINE CHANGED
{*a = 1;*b = 2;return *a + *b;
}int main(void)
{int sum;int num_1;int num_2;sum = add(&num_1, num_2);printf("The sum is %d.\n", sum);return 0;
}
接下来,我们编译运行一下,观察输出结果:
% gcc -o test test.c
% ./test
The sum is 3.
%
什么?加不加 restrict
没区别?哦!!!这可能与编译器优化有关,我是不是应该打开编译器优化选项啊?!
于是,我便添加了编译器优化选项 -O1
。但是,两个程序段的输出并没有变化。
正当我一筹莫展的时候,我突然想到了汇编。一个程序的执行效率如何,不能光看执行结果,还需要落实到汇编代码上。于是,我使用 gcc -O1 -S test.c
执行两个程序段的汇编,将得到的部分汇编代码(add()
部分)比较如下。
/* WITHOUT restrict */
addmov w8, #1str w8, [x0]mov w8, #2str w8, [x1]ldr w8, [x0]add w0, w8, #2ret/* WITH restrict */
addmov w8, #1str w8, [x0]mov w8, #2str w8, [x1]mov w0, #3ret
可以看到,加了 restrict
后,虽然运行结果不变,但汇编指令减少了 1 条。接下来,我们将逐条分析该程序段的汇编指令。
首先,两个程序段的前四条汇编指令都是相同,具体分析见注释:
addmov w8, #1 // *a = 1str w8, [x0]mov w8, #2 // *b = 2str w8, [x1]
在处理返回值时,不加 restrict
的处理为:
ldr w8, [x0] /* [1] */add w0, w8, #2 /* [2] */
[1]
:取 *a
的值;
[2]
:加上 2
后返回。
再来看一下我们的返回语句:return *a + *b;
那么问题出现了:为什么取
*a
的值是去相应的地址取值,而取*b
的值却直接用数字2
代替呢?
这个问题暂时留在这,我们接着看加了 restrict
的处理:
mov w0, #3 /* [1] */
[1]
:直接返回 3
。
看到这里,聪明的你一定大概理解了 restrict
的作用了!
原来:
加了
restrict
后,表明指针变量a
与b
是修改其指向对象的唯一途径。那么在对a
和b
指向的对象赋值后,没有其他对其操作的语句了,所以编译器很自信地认为它们的值就是自己刚才写进去的值,不可能会变。而刚才写的值编译器自己太清楚了,当编译器看到最后一条返回语句时,心想:咋还要我加一遍呢?不就是一个1
和一个2
嘛,和不就是3
嘛~
当没加
restrict
时,在对a
和b
指向的对象赋值后,编译器看到返回语句,心想:我刚刚写入的b
对象是2
没错,但a
对象还是1
吗?有可能a
和b
存在着某种联系呢,那我写入b
时岂不是有可能对a
产生影响?算了算了,还是别偷懒了,再去a
地址看看到底是多少吧…
看到这,你应该完全理解了吧!
在加了 restrict
以后,编译器直到别的地方不会对其产生影响,所以自己写入的值是多少,它就一定不会变。但没加 restrict
时,编译器不能确定别的地方是不是会修改改值,所以只能老老实实地去相应的地址查看了。
好的,就此落笔。希望对你有一点点帮助,这是我最大的心愿。
如果方便的话,可以关注一下我的微信公众号:
编程笔记本
谢谢。
浅析 restrict 关键字相关推荐
- 通过反汇编来理解restrict关键字
一次难忘的面试经历 多年前,一次互联网某厂实习生的面试题,题目的代码片段很简单,如下: 1 #include 2 int main()3 {4 int *restrict pInt = (int*)m ...
- C语言中restrict的意义,restrict关键字在C ++中的含义是什么?
正如其他人所说,如果C ++ 14中没有任何意义,那么让我们考虑一下__restrict__与C99相同的GCC扩展restrict. C99 restrict说两个指针不能指向重叠的内存区域.最常见 ...
- [C/C++学习] restrict 关键字
本篇博客主要谈论 C 语言关键字 restrict,只用于修饰指针,功能是帮助编译器进行优化!值得注意的是,优化需要就事论事,经过分析:如果发现确实优化不了,就不优化了.不加 restrict 关键字 ...
- C99中的restrict关键字
今天读APUE,看到某个函数原型的声明: int stat ( const char * restrict pathname, struct stat * restr ...
- C语言中restrict关键字学习
简介: restrict是c99标准引入的,它只可以用于限定和约束指针,并表明指针是访问一个数据对象的唯一且初始的方式.即它告诉编译器,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不 ...
- C语言的 restrict 关键字的作用
restrict 这个关键字到底有什么用,还是用代码看得清楚.这里,c 标准说明中用了如下的例子: #include <stdio.h>int foo(int *a, int *b) {* ...
- restrict关键字用法
c99中新增加了一个类型定义,就是restrict. 概括的说,关键字restrict只用于限定指针:该关键字用于告知编译器,所有修改该指针所指向内容的操作全部都是基于(base on)该指针的,即不 ...
- C/C++中的restrict关键字
restrict用于限定和约束指针,表示这个指针只访问这块内存的唯一方式,也就是告诉编译器,这块内存中的内容的操作都只会通过这个指针,而不会通过其他变量或者指针.这个指针有两个作用,一个是告诉编译器, ...
- restrict关键字
c99中新增加了一个类型定义,就是restrict 看了下网上的相关贴子,但还是问题解决的不够.下面是相关一个文章,我将在后面再加相关说明: 那么restrict的意义是什么呢? 概括的说,关键字re ...
最新文章
- 面试:如何从大量的 URL 中找出相同的 URL?
- 博客编辑神器:Markdown编辑器
- 优达学城深度学习之六——TensorFlow卷积神经网络
- java sql注入正则表达式_php防止sql注入示例分析和几种常见攻击正则表达式
- C# lambda递归
- python基础:列表(list)
- 剪枝算法(算法优化)
- 小米盒子2刷android tv,【二次搬运】小米盒子3S刷Android TV教程
- pyecharts源码解读(15)图表类包charts之组合图表: 选项卡Tab
- unity3d android访问剪贴板,Airtest 和 poco 的 swipe 接口使用总结
- 自动打卡python脚本_Centos7从零开始配置py每日自动打卡脚本
- element-ui+vue,翻页添加首页、尾页跳转按钮
- Flink on yarn集群HA配置
- java简单的增删改查项目 ATM机
- webstorm2019 汉化后无法设置 webstorm最新汉化包
- 学生dreamweaver网页设计作业成品:电商网页设计——仿淘宝静态首页(HTML+CSS)
- 南信大电脑开机自动连接校园网
- 第二周:四人小组项目
- Unity WebGL错误集锦
- 微信小程序原生常用语法 1
热门文章
- RabbitMQ学习笔记 03、交换机模式(4种)
- 什么是遥感?什么是定量遥感?什么是多光谱、高光谱和超光谱?
- 封装自己专属的真正的纯净版Windows系统过程记录(2)——使用习惯设置,软件安装与优化设置
- Digital Camera Sensor 曝光三要素
- Primavera P6 EPPM R8.3.X Patch/Update(补丁/更新)
- 再看《周渔的火车》 转载一篇不错的影评
- 浅析如何把逻辑地址转换为物理地址
- tensorflow数据结构-MetaInfoDef
- 浏览器记住账号密码后,在密码输入框屏蔽浏览器的弹出提示
- mysql存储过程之游标