-
Notifications
You must be signed in to change notification settings - Fork 160
/
restrict.c
94 lines (77 loc) · 2.13 KB
/
restrict.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
/*
# restrict
Identifier qualifier.
Says to the compiler that every pointer passed to a function that is marked restrictd
does not refer to the same element.
Can only qualify pointers. The most common use case is to qualify pointers passed to functions.
Programmers must ensure that temselves. if they don't, undefined behaviour.
No behaviour change, but allows for further compiler optimization,
so it should be used whenever possible. See generated assembly to spot the difference.
Great example showing how restrict could help optimize things: http://en.wikipedia.org/wiki/Restrict
*/
#include "common.h"
void restrict_double_add(int * restrict i, int * restrict j, int * restrict add) {
*i += *add;
*j += *add;
}
void double_add(int *i, int *j, int *add) {
*i += *add;
*j += *add;
}
/* It makes no sense to mark a single pointer as restricted. */
void restrict_double_add_one_restrict(int * restrict i, int *j, int *add) {
*i += *add;
*j += *add;
}
int main(void) {
#if __STDC_VERSION__ >= 199901L
{
int i = 0;
int j = 0;
int add = 1;
double_add(&i, &j, &add);
assert(i == 1);
assert(j == 1);
}
{
int i = 0;
int j = 0;
int add = 1;
restrict_double_add(&i, &j, &add);
assert(i == 1);
assert(j == 1);
}
#ifdef UNDEFINED_BEHAVIOUR
/*
BAD: undefined behaviour, because the same pointer is passed twice
The compiler should be able to spot that one... but gcc 4.7 did not.
*/
{
int i = 1;
int j = 1;
restrict_double_add(&i, &j, &i);
if (i != 2)
printf("restrict i = %d\n", i);
if (j != 3)
printf("restrict j = %d\n", j);
}
#endif
/* OK: not restrict */
{
int i = 1;
int j = 1;
double_add(&i, &j, &i);
assert(i == 2);
assert(j == 3);
}
/* Outside functions. */
/* TODO what does it mean then? */
{
int i;
int * restrict ip;
}
/* ERROR: can only qualify pointers */
/*int restrict ip;*/
#endif
return EXIT_SUCCESS;
}