我们希望某个对象(内存空间)不被修改的通常做法是什么?声明该空间的const类型,但是这样真的可以吗?是不是的,由于const空间对象的指针是可以付给一个非const值指针的。所以这仍然无法不让该空间被修改。

const int a=10;
int * b=&a;

虽然,编译器会报警告“ 警告:初始化丢弃了指针目标类型的限定”,这个意思是,b失去了对目标对象的const的限定。但是通过,并且,可以通过指针b更改它们共同指向的空间。

const int a=10;
int b=(int)&a;
int * c=(int *)b;

这种写法和上面的效果一样,却连警告都不报,这就可以看到C语言类型转换的功能有多大,并且有多危险。当我们将a的地址转换成int类型的时候,编译器不会认为这是一个严重的事情(因为int类型并不能访问内存空间),之后再从int类型转换到int *类型,这个时候,编译器也很难确定这是否会出现不安全的地方。所以,这样一做,就骗过了C编译器。而前面的方法中,编译器明显看到两个指针之间的赋值初始化,是有不安全的地方的(丢掉了const的对象设定),所以发出警告。

不过,一句话,const是无法保证某个对象不被更改的。所以C99提出了一个restrict关键字。它是修饰指针的,表达出的意思是,对该指针指向的空间的访问,只能从这个指针进入。这样,如果该关键字在加上restrict,就会达到锁定该空间。当然,restrict不一定只是为了建立一个完全常态的空间,它的本意是限制该空间只能通过该指针进行访问。

restrict pointer是c99新标准提出的一个很著名的概念叫着——受限指针。这种指针的声明是为了,编译达到更好的优化,它暗示编译器,某个指针指向的空间,只能从该指针访问。但是这种暗示却是对程序员的要求,而编译器只是在这种暗示的基础上作一些优化。

restrict只可以用在指针身上。如果一个指针被restrict修饰,那么就在它(这个指针)和它所指向的对象之间建立了一种特殊的联系──只能用这个指针或者这个指针的表达式来访问这个对象的值

一个指针指向一个内存地址。同一块内存可以由多个指针来访问并在程序运行时修改它(这块内存)。restrict告诉编译器,如果一块由一个被restrict修饰的指针所指向的内存被修改了,那么没有其它的指针可以来访问这块内存。编译器可能会选择一种方式来优化代码中调用被restrict修饰的指针的部分,这可能导致错误发生。程序员有责任来确保正确地按照他们所设想的来使用被restrict修饰的指针,否则的话,可能会发生意想不到的结果。

C库中的例子
         C库中有两个函数可以从一个位置把字节复制到另一个位置。在C99标准下,它们的原型如下:

void * memcpy(void * restrict s1, const void * restrict s2, size_t n);
void * memove(void * s1, const void * s2, size_t n);

这两个函数均从s2指向的位置复制n字节数据到s1指向的位置,且均返回s1的值。两者之间的差别由关键字restrict造成,即memcpy()可以假定两个内存区域没有重叠。memmove()函数则不做这个假定,因此,复制过程类似于首先将所有字节复制到一个临时缓冲区,然后再复制到最终目的地。如果两个区域存在重叠时使用memcpy()会怎样?其行为是不可预知的,既可以正常工作,也可能失败。在不应该使用memcpy()时,编译器不会禁止使用memcpy()。因此,使用memcpy()时,您必须确保没有重叠区域。这是程序员的任务的一部分。关键字restrict有两个读者。一个是编译器,它告诉编译器可以自由地做一些有关优化的假定。另一个读者是用户,他告诉用户仅使用满足restrict要求的参数。一般,编译器无法检查您是否遵循了这一限制,如果您蔑视它也就是在让自己冒险。

restrict关键字(暗示编译器,某个指针指向的空间,只能从该指针访问)的更多相关文章

  1. ”危险“的RESTRICT与GCC的编译优化(编程者对编译器所做的一个“承诺”:使用restrict修饰过的指针,它所指向的内容只能经由该指针修改)

    restrict是C99标准中新添加的关键字,对于从C89标准开始起步学习C语言的同学来说(包括我),第一次看到restrict还是相当陌生的.Wikipedia给出的解释如下: In the C p ...

  2. 指针常量&常量指针&指向常量的指针常量

    搞不懂不吃晚饭 (1)指针常量 指针常量是一个常量,但是是指针修饰的. 格式:int * const p; 例如 int a, b; int * const p = &a;//指针常量 //分 ...

  3. 关于C++的子类指针指向父类

    基类指针引用派生类对象 用基类指针引用一个派生类对象,由于派生类对象也是基类的对象,所以这种引用是安全的; 但是只能引用基类成员. 若试图通过基类指针引用那些只在派生类中才有的成员,编译器会报告语法错 ...

  4. 指针的指针&指向指针数组的指针

    一.指针的指针    指针的指针看上去有些令人费解.它们的声明有两个星号.例如:        char ** cp;    如果有三个星号,那就是指针的指针的指针,四个星号就是指针的指针的指针的指针 ...

  5. 父类指针指向子类内存,为什么当父类的成员函数不加virtual时,访问的还是父类的成员函数,而不是子类同名的成员函数

    我认为是这样,类的成员函数都在代码区,不同的类的成员函数在代码区有自己的类名称空间限制,类的虚函数在虚函数表中,程序执行的时候,是先在虚函数表中找该成员函数,如果没有找到,就去该类在代码区的成员函数中 ...

  6. 剑指offer25:复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),结果返回复制后复杂链表的head。

    1 题目描述 输入一个复杂链表(每个节点中有节点值,以及两个指针,一个指向下一个节点,另一个特殊指针指向任意一个节点),返回结果为复制后复杂链表的head.(注意,输出结果中请不要返回参数中的节点引用 ...

  7. 给指针malloc分配空间后就等于数组吗?

    首先回答这个的问题:严格的说不等于数组,但是可以认为它是个数组一样的使用而不产生任何问题.不过既然这样,那它应该算是个数组吧.所以,一般我们都用“动态数组”这种名字来称呼这种东西. 要讲清楚这个东西, ...

  8. 你好,C++(40)7.1 一切指针都是纸老虎:彻底理解指针

    第7章 C++世界的奇人异事 在武侠小说中,初入武林的毛头小子总是要遇到几位奇人,发生几件异事,经过高人的指点,经历一番磨炼,方能武功精进,从新手成长为高手.在C++世界,同样有诸多的奇人异事.在C+ ...

  9. 给指针malloc分配空间后就等于数组吗?【转】

    首先回答你的问题:严格的说不等于数组,但是可以认为它是个数组一样的使用而不产生任何问题. 不过既然这样,那它应该算是个数组吧.所以,一般我们都用“动态数组”这种名字来称呼这种东西. 要讲清楚这个东西, ...

随机推荐

  1. #一周五# VS2015 CTP6, TFS2015 CTP1更新,老衣的开发工具汇总,2015 MVP 社区巡讲

    又到周五,这一周博主我工作效率极高,每天更新博客一篇,<快速创建网站>系列已经进程大半了,希望这个系列能够对大家有所帮助.今天周五了,博主要休息一下,就给大家唠叨一下这段时间都发生了什么. ...

  2. 【Android 应用开发】AndroidUI设计 之 图片浏览器

    图片浏览器效果图 : 源码下载地址 : -- CSDN : http://download.csdn.net/detail/han1202012/6875083 -- GitHub : https:/ ...

  3. SpriteBuilder中如何平均拉伸精灵帧动画的距离

    首先要在Timeline中选中所有的精灵帧,可以通过如下2种的任意一种办法达成: 1按下Shift键的同时鼠标单击它们 2鼠标在Timeline空白区拖拽直到拉出的矩形包围住所有精灵帧方块后放开鼠标. ...

  4. 俺的新书《Sencha Touch实战》终于出版了

    内容简介:Sencha框架是第一个基于HTML 5的移动也能给予框架,可以让Web应用看起来像网络应用.美丽的用户 界面 组件和丰富的数据管理,全部基于最新的HTML 5和CSS 3的Web标准,全部 ...

  5. 如何设计一个可用的web容器

    之前在另外一个平台(http://www.jointforce.com/jfperiodical/article/1035)发表的一篇文章,现在发布到自己的博客上. 开发一个web容器涉及很多不同方面 ...

  6. dex分包方案

    当一个app的功能越来越复杂,代码量越来越多,也许有一天便会突然遇到下列现象: 1. 生成的apk在2.3以前的机器无法安装,提示INSTALL_FAILED_DEXOPT 2. 方法数量过多,编译时 ...

  7. SharePoint 2010 之soap:Server服务器无法处理请求

    算是一个下马威?!刚刚部署上的SharePoint2010环境,感觉很欣喜,开始操作,结果装上Designer2010,打开页面,居然报错 错误内容:soap:Server服务器无法处理请求. --- ...

  8. 【15】-java实现二分查找

    二分查找在面试中经常被遇到,这个方法十分优雅 介绍 二分查找可以解决(预排序数组的查找)问题:只要数组中包含T(即要查找的值),那么通过不断缩小包含T的范围,最终就可以找到它.一开始,范围覆盖整个数组 ...

  9. DB Query Analyzer 5.03 is distributed, EXCEL table name will be enclosed in square bracket

      DB Query Analyzer 5.03 is distributed, table name will be enclosed in square bracket automatically ...

  10. 继续死磕SDRAM控制器

    SDRAM控制器 博主上一篇介绍了一些SDRAM的基本原理是否有必要学习使用纯Verilog写一个SDRAM控制器,接下来记录SDRAM控制器的工作原理.首先是上电初始化. 上电初始化 时序图中,tR ...