-
Notifications
You must be signed in to change notification settings - Fork 0
/
tatomic.c
94 lines (81 loc) · 2.4 KB
/
tatomic.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
#include <stdint.h>
#include <stdio.h>
#include <signal.h>
int main(void);
/*
* XXX must be compiled with -DUSE_VOLATILE to qualify nonatomic_t with
* "volatile" for correctness in C89 or newer.
*/
/*
* defines an integer type 'nonatomic_t' and declares a variable 'x' using it
*
* also defines an identical-sized type 'testint_t' that will never be
* qualified as volatile.
*/
#include "tatomic.h"
int
main()
{
/*
* catch_signal() will increment the external variable 'x'
*/
(void) signal(SIGUSR1, catch_signal);
while (1) {
register testint_t nvtmp;
register nonatomic_t tmp;
/*
* all of the following statements will be optimized away if
* nonatomic_t is qualified with "volatile" (i.e.this is
* compiled with "-DUSE_VOLATILE")
*/
/* XXX no sequence point -- may always be optimized away */
if (!(x == x)) {
/*
* XXX with GCC 4.1.x and 4.2.x this statement will
* always be optimized away, if nonatomic_t is not
* qualified as volatile (i.e. if compiled without
* USE_VOLATILE), even if '-O0' is used.
*
* I.e. GCC is "smart" enough to always eliminate code
* bounded by tautological tests, and this is not a
* feature of the optimizer, per se.
*
* XXX however GCC _should_ probably eliminate this
* even when 'x' is qualified as "volatile" because
* there are no sequence points in the expression, yet
* it does not.
*/
puts("x does not equal X!");
}
if (tmp = x, !(tmp == x)) {
puts("tmp does not equal X!");
}
if (nvtmp = x, !(nvtmp == x)) {
puts("nvtmp does not equal X!");
}
/* XXX no sequence point -- may always be optimized away */
if ((x - x)) {
/*
* XXX, as above.
*
* Interestingly GCC generates the same machine code
* (for x86(_64) at least) for this expression as it
* does for the one above. PCC does not of course.
*/
puts("x - x does not equal 0!");
}
if (tmp = x, (tmp - x)) {
puts("tmp - X does not equal 0!");
}
if (nvtmp = x, (nvtmp - x)) {
puts("nvtmp - X does not equal 0!");
}
}
/* NOTREACHED */
}
/*
* Local Variables:
* eval: (make-local-variable 'compile-command)
* compile-command: (let ((fn (file-name-sans-extension (file-name-nondirectory (buffer-file-name))))) (concat "rm -f " fn "; " (default-value 'compile-command) " OPTIM='-O3' CPPFLAGS='-DUSE_VOLATILE' LDLIBS=tatomic-sigusr.c " fn " && echo 'send SIGUSR1 while running'"))
* End:
*/