2012年(46)
分类: C/C++
2012-04-27 12:04:46
restrict关键字
摘自:http://bdxnote.blog.163.com/blog/static/84442352010017185053/
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
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;
}
此时,编译报错:
> 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
>
报错了,在Solaris和Suse上报同样的错;把test_restrict.cpp重命名为test_restrict.c之后,就可以编译通过了:
> gcc -o test test_restrict.c -std=c99
>
使用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"