restrict关键字

来源:互联网 发布:数据集成架构 编辑:程序博客网 时间:2024/05/02 02:04

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"


转自:http://blog.csdn.net/cp1300/article/details/7773239

原创粉丝点击