8. restrict 关键字
restrict 关键字 是 C 语言的 C99 标准中引入的一个关键字,它只能修饰指针的关键字。它用于向编译器提供承诺,此指针只能由这一个指针来操作这段内存,没有其它指针来指向这段内存。以便编译器使用更有力的优化策略对这段代码进行优化。
语法
数据类型 * restrict 指针变量名;
示例:
例如在 Linux系统下的 C 语言库函数中的 strcat 函数的定义如下:
char *strcat(char *restrict dst, const char *restrict src);
我们编写如下程序:
// filename: restrict.c
#include <stdio.h>
#include <string.h>
int main(int argc, char * argv[]) {
char str1[100] = "hello ";
char str2[100] = "world!";
// 不会有restrict 警告
strcat(str1, str2);
printf("str1: %s\n", str1);
// 以下 GCC 编译器会有restrict 警告 结果也会不确定。
strcat(str1, str1); // strcat 的形式参数的两个指针指向和同一个地址。
printf("str1: %s\n", str1);
return 0;
}
编译和运行结果如下:
weimingze@mzstudio:~$ gcc -o restrict restrict.c -Wall
restrict.c: In function ‘main’:
restrict.c:14:12: warning: passing argument 1 to ‘restrict’-qualified parameter aliases with argument 2 [-Wrestrict]
14 | strcat(str1, str1); // strcat 的形式参数的两个指针指向和同一个地址。
| ^~~~ ~~~~
weimingze@mzstudio:~$ ./restrict
str1: hello world!
str1: hello world!hello world!
重上面示例可以看出。由于 strcat 进行了优化。我们使用 strcat(str1, str2); 进行操作相对是比较安全的,因为两块内存是不同的区域。当我们使用 strcat(str1, str1); 对同一个地址的数据进行复制时,编译器会给出警告。
注意事项
- restrict 是程序编写人员给编译器的承诺。编译器并不会检查此指针是否有别名。
- 违反 restrict 的承诺,程序执行结果可能是未定义行为。