restrict 关键字 的作用

arcii9 2017-06-24 12:07:57
经过实验,restrict 没有限制其他指针修改同一个地址中的内容。这和书上说的不一致。restrict 的真正含义希望得到解答。

int a=0;
int *restrict p=&a;
int *ptr=&a;
*ptr=2;
最后结果*ptr为2。restrict关键字没起到作用,能帮忙解释一下restrict的用法么?
...全文
293 4 打赏 收藏 转发到动态 举报
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
arcii9 2017-06-24
  • 打赏
  • 举报
回复
明白啦~十分感谢上面的回复~受到帮助真是太感动啦~
paschen 2017-06-24
  • 打赏
  • 举报
回复
restrict 只是告诉编译器,以便于优化 而并不是用于确保地址不重叠
成长记情 2017-06-24
  • 打赏
  • 举报
回复
restrict的定义是 ( restrict type qualifier ): During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined. 也就是说,restrict是程序员告诉编译器额外的信息:在restric所修饰指针P所生存的作用域内,程序员保证只有指针P是指向P所指向的这片内存的,没有‘别人’可以修改这个指针指向的这片内存,所有修改都得通过这个指针来。这就有助于编译器优化代码,如果程序员违反这个约定,则行为时未定义的。 举个栗子

int fun(int *a, int *b)
{
    *a = 5;
    *b = 6;
    return *a + *b;    //不一定返回11
}
如果指针a和指针b指向同一个对象,*b = 6会导致 *a为6,返回12.所以编译器在做return *a + *b 的时候需要重新读取*a 的值。

fun:
    movl $5,(%rdi)    #存储5到*a
    movl $6,(%rsi)    #存储6到*b
    movl (%rdi),%eax    #重新读取*a
    addl $6,%eax      #加上6
    ret
如果我们确保两个指针不会指向同一个对象,则可以使用restrict修饰指针变量

int rfun(int *restrict a, int *restrict b)
{
    *a = 5;
    *b = 6;
    return *a + *b; 
}
编译器可以根据这个信息做优化

rfun:
    movl $11,%eax   #在编译期就可以计算出11
    movl $5,(%rdi)    #存储5到*a
    movl $6,(%rsi)    #存储6到*b
    ret
总而言之,restrict是为了告诉编译器指针独享指针所指向的内存,从而编译器能生成更优化的机器码。编译器是无法检测指针是否独享指针指向内存的,所以如果程序员使用restrict,那么程序员也需要遵守相应的契约保证才能得出正确的代码,否则,行为是未定义的。
成长记情 2017-06-24
  • 打赏
  • 举报
回复
restrict的定义是 ( restrict type qualifier ): During each execution of a block in which a restricted pointer P is declared (typically each execution of a function body in which P is a function parameter), if some object that is accessible through P (directly or indirectly) is modified, by any means, then all accesses to that object (both reads and writes) in that block must occur through P (directly or indirectly), otherwise the behavior is undefined. 也就是说,restrict是程序员告诉编译器额外的信息:在restric所修饰指针P所生存的作用域内,程序员保证只有指针P是指向P所指向的这片内存的,没有‘别人’可以修改这个指针指向的这片内存,所有修改都得通过这个指针来。这就有助于编译器优化代码,如果程序员违反这个约定,则行为时未定义的。 举个栗子

int fun(int *a, int *b)
{
    *a = 5;
    *b = 6;
    return *a + *b;    //不一定返回11
}
如果指针a和指针b指向同一个对象,*b = 6会导致 *a为6,返回12.所以编译器在做return *a + *b 的时候需要重新读取*a 的值。

fun:
    movl $5,(%rdi)    #存储5到*a
    movl $6,(%rsi)    #存储6到*b
    movl (%rdi),%eax    #重新读取*a
    addl $6,%eax      #加上6
    ret
如果我们确保两个指针不会指向同一个对象,则可以使用restrict修饰指针变量

int rfun(int *restrict a, int *restrict b)
{
    *a = 5;
    *b = 6;
    return *a + *b; 
}
编译器可以根据这个信息做优化

rfun:
    movl $11,%eax   #在编译期就可以计算出11
    movl $5,(%rdi)    #存储5到*a
    movl $6,(%rsi)    #存储6到*b
    ret
总而言之,restrict是为了告诉编译器指针独享指针所指向的内存,从而编译器能生成更优化的机器码。编译器是无法检测指针是否独享指针指向内存的,所以如果程序员使用restrict,那么程序员也需要遵守相应的契约保证才能得出正确的代码,否则,行为时未定义的。

69,374

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧