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 <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"


<think>好的,用户想知道C++是否支持restrict关键字。首先,我需要回忆一下C和C++的关键字差异。记得在C语言中,restrict是C99标准引入的,用于指针优化,告诉编译器指针是唯一访问该数据的方式。而C++的标准中好像没有这个关键字。不过,很多编译器比如GCC和Clang可能以扩展形式支持,比如使用__restrict__或者__restrict。需要确认不同编译器的具体实现。 然后,用户可能在使用C++时遇到了需要优化指针的情况,或者从C代码移植过来,所以想知道在C++中如何处理。需要解释标准不支持,但编译器可能有扩展。还要注意C++的替代方法,比如使用引用或STL容器来避免指针别名问题。 另外,用户提供的引用内容提到C++编译器可能支持,因为很多同时是C编译器。这点需要强调,比如MSVC的__restrictGCC的__restrict__。同时,C++11及以后的标准是否有变化?目前了解是没有,但最好确认最新标准。 最后,用户可能需要示例代码,说明如何在C++中使用这些扩展,以及何时使用它们合适。要提醒用户注意可移植性问题,因为不同编译器的支持可能不同。总结回答时要分点,结构清晰,涵盖标准情况、编译器扩展、替代方案和使用建议。</think>关于C++是否支持`restrict`关键字的解答: ### 核心结论 1. **C++标准不支持`restrict`** C++标准(包括C++11/14/17/20)未将`restrict`作为关键字引入,这与C语言的C99标准不同[^1]。 2. **编译器提供的扩展支持** 主流编译器通过非标准扩展实现类似功能: - **GCC/Clang**: 使用`__restrict__` ```cpp void func(int* __restrict__ a, int* __restrict__ b); ``` - **MSVC**: 使用`__restrict` ```cpp void func(int* __restrict a, int* __restrict b); ``` 3. **应用场景与作用** 该关键字编译器承诺:指针指向的内存区域不存在数据重叠,帮助编译器进行激进的优化(如指令重排、循环展开),常见于数值计算、图像处理等高性能代码中。 4. **C++的替代方案** - 使用引用替代指针(天然具备非别名特性) - 使用`std::vector`等容器管理数据 - 利用`#pragma`指令进行局部优化提示 ### 代码示例对比 ```cpp // C语言示例(C99标准) void c_func(int* restrict a, int* restrict b); // C++示例(GCC扩展) void cpp_func(int* __restrict__ a, int* __restrict__ b); ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值