restrict
允许编译器优化某部分代码以更好地支持计算,它只能用于指针,表明该指针是访问数据对象的唯一且初始的方式。
用于告诉编译器,对象已经被指针所引用,不能通过除该指针外所有其他直接或间接的方式修改该对象的内容。
#include<stdio.h>
int main()
{
int arr[10];
int *restrict restar=(int *)malloc(10*sizeof(int));
int *par=ar;
for(int n=0;n<10;n++)
{
par[n]+=5;
restar[n]+=5;
arr[n]*=2;
par[n]+=3;
restar[n]+=3;
}
}
因为restar是访问它所指向的数据块的唯一且初始的方式,编译器可以把涉及restart的两条语句替换成下面这条语句,效果相同
restar[n]+=8;
但是把与par相关的两条语句替换成下面的语句,将导致计算错误
par[n]+=8;
因为for循环在par两次访问相同的数据之间,用ar改变了该数据的值.在该例中,如果使用了 restrict 关键字,编译器就可以选择捷径优化计算
restrict还可用于函数形参中的指针,这意味着编译器可以假定在函数体内其他
标识符不会修改该指针指向的数据,而且编译器可以尝试对其优化,使其不做别的用途
volatile 类型限定符
告知计算机,代理可以改变该变量的值,通常,它被用于硬件地址及 在其他程序或同时运行的线程中共享数据,例如,一个地址上可能存储着当前的时钟时间,无论程序做什么,地址上的值都随着时间的变化而改变,或者一个地址用于接受另一台计算机传入的信息.简单地说就是防止编译器对代码进行优化。 确保本条指令不会因编译器的优化而省略,且要求每次直接读值.精确地说就是,优化器在用到这个变量时必须每次都小心地重新读取这个变量的值,而不是使用保存在寄存器里的备份。
volatile int locl; //易变型变量,locl 是一个易变的位置说明这变量可能会被意想不到的改变,这样,编译器就不会假设这个变量的值了 volatile int *ploc; //指向易变型变量的指针, val1=x; val2=x; 智能的(进行优化的)编译器会注意到以上代码使用了两次x,但并未改变它的值,于是编译器 把x的值临时存储在寄存器中,然后在val2需要使用x时,才从寄存器中(而不是从原始内存位置 上)读取x的值,以节约时间,这个过程被称为高速缓存。 但是如果一些其他代理在以上两句语句之间改变了x的值,就不能这样优化了,如果没有 volatile 关键字,编译器就不会知道这种事情是否会发生。而现在,如果未使用volatile 关键字,编译 器会假定变量的值在使用过程中不变,然后尝试优化 volatile const int loc; //程序不能改变的变量,但是可以通过代理改变 const volatile int *ploc;