登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

她三哥

Tsange

 
 
 

日志

 
 

restrict关键字  

2010-01-17 01:08:50|  分类: C/VC/C++ |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

restrict关键字的含义是:约束、限定、严格的;
这个关键字是C99标准中新增加的;
简单地说,restrict关键字只用于限定和约束指针;它告诉编译器,所有修改该指针所指向内存中内容的操作,全都必须基于(base on)该指针,即:不存在其它进行修改操作的途径;换句话说,所有修改该指针所指向内存中内容的操作都必须通过该指针来修改,而不能通过其它途径(其它变量或指针)来修改;这样做的好处是,能帮助编译器进行更好的优化代码,生成更有效率的汇编代码;
实验:
int test_restrict(int* x, int* y)
{
  *x = 0;
  *y = 1;
  return *x;
}
很显然,test_restrict()函数的返回值是0,除非参数x和y的值相同;可以想象,99%的情况下该函数都会返回0而不是1;然而编译器必须保证生成100%正确的代码,因此,编译器不能将原有代码替换成下面的更优版本的代码:
int test_restrict(int* x, int* y)
{
  *x = 0;
  *y = 1;
  return 0;   //<---直接替换成0;
}
C99标准中新增加了restrict这个关键字,关键字restrict就可以帮助编译器安全地进行代码优化了:
int test_restrict(int* restrict x, int* restrict y)
{
  *x = 0;
  *y = 1;
  return *x;
}
由于使用restrict关键字来修饰参数x了,所以,指针x是修改指针x所指向内存中内容的唯一途径,编译器可以确认"*y = 1;"这行代码绝对不会修改*x的内容,因此,编译器可以安全地把代码优化为:
int test_restrict(int* restrict x, int* restrict y)
{
  *x = 0;
  *y = 1;
  return 0;   //<---直接替换成0;
}
注意:关键字restrict是C99标准中新增加的关键字,C++目前仍未引入;编译时,可通过在gcc的命令行使用参数"-std=c99"来开启对C99标准的支持;即:目前C++语言还不支持关键字restrict,而C语言支持;所以,restrict关键字目前只能出现在.c文件中,而不能出现在.cpp文件中;

实验一:test_restrict.cpp
#include <stdio.h>

int test_restrict(int* restrict x, int* restrict y)
{
  *x = 0;
  *y = 1;
  return *x;
}

int main(int argc, char** argv)
{
  int a = -1, b = -2;
  a = test_restrict(&a, &b);
  return a;
}
此时,编译报错:
sxit@sxit-bqm:~/test> gcc -o test test_restrict.cpp -std=c99
cc1plus: warning: command line option "-std=c99" is valid for C/ObjC but not for C++
test_restrict.cpp:3: error: expected ',' or '...' before 'x'
test_restrict.cpp: In function 'int test_restrict(int*)':
test_restrict.cpp:5: error: 'x' was not declared in this scope
test_restrict.cpp:6: error: 'y' was not declared in this scope
test_restrict.cpp: In function 'int main(int, char**)':
test_restrict.cpp:3: error: too many arguments to function 'int test_restrict(int*)'
test_restrict.cpp:13: error: at this point in file
sxit@sxit-bqm:~/test>
报错了,在Solaris和Suse上报同样的错;把test_restrict.cpp重命名为test_restrict.c之后,就可以编译通过了:
sxit@sxit-bqm:~/test> gcc -o test test_restrict.c -std=c99
sxit@sxit-bqm:~/test>

使用restrict关键编译过的汇编代码:
test_restrict:
!#PROLOGUE# 0
!#PROLOGUE# 1
mov     4, %g1
st      %g1, [%o0]
mov     1, %o5
st      %o5, [%o1]
retl
mov     4, %o0          <------返回值:返回立即数4;说明已经被优化了;
.size   test_restrict, .-test_restrict
.section        ".rodata"
.align 8

没有使用restrict关键编译过的汇编代码:
test_restrict:  -----without restrict
!#PROLOGUE# 0
!#PROLOGUE# 1
mov     4, %g1
st      %g1, [%o0]
mov     1, %o5
st      %o5, [%o1]
retl
ld      [%o0], %o0      <------返回值:取变量的值作为返回值;说明没有被优化;
.size   test_restrict, .-test_restrict
.section        ".rodata"

  评论这张
 
阅读(4091)| 评论(0)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018