关键字restrict简介

本文摘自: http://www.oschina.net/question/32294_53573
restrict是C99引入的新关键字,它用于 声明只会通过该指针对其指向的内存空间进行读写操作,以便编译器能进行更好的优化。
我们来看一个跟memcpy/memmove类似的问题。下面的函数将两个数组中对应的元素相加,结果保存在第三个数组中。
 
   

void vector_add ( const double * x , const double * y , double * result )
{
int i ;
for ( i = 0 ; i < 64 ; ++ i )
result [ i ] = x [ i ] + y [ i ];
}

如果这个函数要在多处理器的计算机上执行,编译器可以做这样的优化:把这一个循环拆成两个循环,一个处理器计算i值从0到31的循 环,另一个处理器计算i值从32到63的循环,这样两个处理器可以同时工作,使计算时间缩短一半。但是这样的编译优化能保证得出正确结果吗?假如result和x所指的内存区间是重叠的,result[0]其实是x[1],result[i]其实是x[i+1],这两个处理器就不能各干各的事情了,因为第二个处理器的工作依赖于第一个处理器的最终计算结果,这种情况下编译优化的结果是错的。这样看来编译器是不敢随便做优化了,那么多处理器提供的并行性就无法利用,岂不可惜?为此,C99引入restrict关键字,如果程序员把上面的函数声明为 void vector_add(const double *restrict x, const double *restrict y, double *restrict result) ,就是告诉编译器可以放心地对这个函数做优化,程序员自己会保证这些指针所指的内存区间互不重叠。
由于 restrict 是C99引入的新关键字,目前Linux的Man Page还没有更新,所以都没有 restrict 关键字,本书的函数原型都取自Man Page,所以也都没有restrict关键字。但在C99标准中库函数的原型都在必要的地方加了restrict关键字,在 C99 中memcpy的原型是 void * memcpy (void * restrict s1, const void * restrict s2, size_t n); ,就是告诉调用者,这个函数的实现可能会做些优化,编译器也可能会做些优化,传进来的指针不允许指向重叠的内存区间,否则结果可能是错的,而memmove的原型是 void * memmove (void *s1, const void *s2, size_t n); ,没有restrict关键字,说明传给这个函数的指针允许指向重叠的内存区间。在restrict关键字出现之前都是用自然语言描述哪些函数的参数不允许指向重叠的内存区间,例如在C89标准的库函数一章开头提到,本章描述的所有函数,除非特别说明,都不应该接收两个指针参数指向重叠的内存区间,例如调用sprintf时传进来的格式化字符串和结果字符串的首地址相同,诸如此类的调用都是非法的。本书也遵循这一惯例,除非像memmove这样特别说明之外,都表示“不允许”。
关于restrict关键字更详细的解释可以参考[ BeganFORTRAN]

<think>好的,用户想知道C++是否支持restrict关键字。首先,我需要回忆一下C和C++的关键字差异。记得在C语言中,restrict是C99标准引入的,用于指针优化,告诉编译器指针是唯一访问该数据的方式。而C++的标准中好像没有这个关键字。不过,很多编译器比如GCC和Clang可能以扩展形式支持,比如使用__restrict__或者__restrict。需要确认不同编译器的具体实现。 然后,用户可能在使用C++时遇到了需要优化指针的情况,或者从C代码移植过来,所以想知道在C++中如何处理。需要解释标准不支持,但编译器可能有扩展。还要注意C++的替代方法,比如使用引用或STL容器来避免指针别名问题。 另外,用户提供的引用内容提到C++编译器可能支持,因为很多同时是C编译器。这点需要强调,比如MSVC的__restrict,GCC的__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); ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值