restrict关键字是否仅对可写入指针有效?相关技术咨询
1. restrict关键字是不是仅对可写指针有意义?
当然不是。restrict的核心作用是向编译器承诺:该指针是其指向内存区域的唯一访问入口——不管这个内存是用来读还是写。
拿memcpy里的const void *restrict src来说,虽然函数里不会修改src指向的内容,但加restrict是告诉编译器:在memcpy执行期间,除了通过src指针之外,没有任何其他方式(比如另一个指针、全局变量)会修改这块内存。有了这个承诺,编译器就可以放心做优化,比如把src的内容一次性加载到寄存器里重复使用,不用每次都重新从内存读取(因为不用担心中途被外部篡改)。
2. 移除memcpy中src的restrict关键字,会改变函数功能吗?
功能正确性不会变,但会影响性能优化空间。
没有restrict的话,编译器必须做最坏假设:src指向的内存可能被其他指针(比如和dest重叠,或者外部的全局指针)修改。这时候编译器就不敢做激进的优化——比如不能用向量指令批量复制,循环展开时也得反复检查内存状态。但只要调用者遵守memcpy的规则(src和dest指向的内存不重叠),函数依然能正确工作,只是运行效率可能打折扣。
3. 函数仅修改a指向的内容时,其他指针需要加restrict吗?
看情况,但如果能满足条件,建议加。
假设函数void fun(float *a, float *b...)只修改a的内容,给b加restrict的意义是:向编译器承诺,在函数执行期间,b指向的内存只能通过b本身访问——不管是读还是写。
比如,如果b是用来只读的输入,加restrict后编译器可以缓存b的值到寄存器,不用每次都从内存读取;如果b虽然不被当前函数修改,但外部也不会改它,这个承诺也能让编译器更放心地优化。
但要注意:如果a和b指向的内存可能重叠,绝对不能加restrict——这会违反承诺,导致编译器生成错误的代码。
内容的提问来源于stack exchange,提问作者Aditya Kurrodu

