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
gcc
command used in this post is "gcc (Ubuntu 9.2.1-9ubuntu2) 9.2.1 20191008"
Top comments (0)