Type qualifier can be used in front of variables to give compiler some hints about the our using purpose of the variable which can help it to generate better code.
register
Example: register int index
This will give the compiler a hint that the variable index will be used heavily and be accessed frequently, it is better to keep it in the machine's register. But remember this is just a hint to compiler, it is not guaranteed this variable will be kept in the register.
Also, since it might be kept in the register, we cannot use the address operator in front of the variable.
Example:
#include <stdio.h>
int main() {
register int i = 0;
int* p = &i;
printf("address of i: %p\n", p);
return 0;
}
Use gcc to compile it, we will get the compilation error:
register.c: In function ‘main’:
register.c:5:5: error: address of register variable ‘i’ requested
5 | int* p = &i;
| ^~~
volatile
Example: volatile char* p
The volatile qualifier will prevent the compiler from optimizing some redundant assignments to a variable. Sometimes compiler will do some optimization to change your code's order or ignore some lines, but those might affect your code logic, especially when you interact with some hardware.
Here is a good example on stackoverflow
restrict
Example: char* restrict s (notice here, unlike register and volatile are put in front of the type, we put restrict after the type)
The restrict qualifier is telling compiler that the pointer it decorated is the ONLY reference to the value it points to in its scope.
We can see an example, the strcpy function in C's standard library string.h:
char * strcpy(char * restrict s1, const char * restrict s2);
Which tell the compiler that s1 and s2 should point to different places. If we have code like this:
#include <stdio.h>
#include <string.h>
int main() {
char s[50] = "hello world";
strcpy(s, s);
puts(s);
return 0;
}
We pass s as the same s1 and s2 parameter. Use gcc to compile it:
$ gcc main.c -o main
Nothing happened, the compiler doesn't even give us a warning. The secret is we need to give the compiler an extra option -Wrestrict to let it report this kind problem.
$ gcc main.c -Wrestrict -o main
We will get the warning info:
memcpy.c: In function ‘main’:
memcpy.c:6:12: warning: passing argument 1 to restrict-qualified parameter aliases with argument 2 [-Wrestrict]
6 | strcpy(s, s);
|
But again remember, we are just giving compiler a hint, whether the compiler use or ignore it, it is up to the compiler or how smart the compiler is. For example, if we change the code to:
#include <stdio.h>
#include <string.h>
int main() {
char s[50] = "hello world";
char* d = s;
strcpy(d, s);
puts(s);
return 0;
}
In this code, although d and s point to the same address, if we use gcc to compile it again, although we still use -Wrestrict flag, it won't give us any warning info.
Reference
- "Programming in C" - Stephen G. Kochan
- gcc warning options
- The
gcccommand used in this post is "gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008"
Top comments (0)