1 | #include <assert.h>
|
---|
2 | int main() {
|
---|
3 |
|
---|
4 | /*
|
---|
5 | The last section established the difference between these four types:
|
---|
6 | */
|
---|
7 |
|
---|
8 | float a [10] ; // array
|
---|
9 | float (*pa )[10] = & a ; // pointer to array
|
---|
10 | float a0 = a[0] ; // element
|
---|
11 | float *pa0 = &(a[0]); // pointer to element
|
---|
12 |
|
---|
13 | /*
|
---|
14 | But the expression used for obtaining the pointer to the first element is pedantic.
|
---|
15 | The root of all C programmer experience with arrays is the shortcut
|
---|
16 | */
|
---|
17 | float *pa0x = a ; // (ok)
|
---|
18 | /*
|
---|
19 | which reproduces @pa0@, in type and value:
|
---|
20 | */
|
---|
21 | assert( pa0 == pa0x );
|
---|
22 | /*
|
---|
23 | The validity of this initialization is unsettling, in the context of the facts established in the last section.
|
---|
24 | Notably, it initializes name @pa0x@ from expression @a@, when they are not of the same type:
|
---|
25 | */
|
---|
26 | assert( sizeof(pa0x) != sizeof(a) );
|
---|
27 |
|
---|
28 |
|
---|
29 |
|
---|
30 |
|
---|
31 |
|
---|
32 |
|
---|
33 |
|
---|
34 |
|
---|
35 |
|
---|
36 |
|
---|
37 |
|
---|
38 |
|
---|
39 |
|
---|
40 | void f( float x[10], float *y ) {
|
---|
41 | static_assert( sizeof(x) == sizeof(void*) );
|
---|
42 | static_assert( sizeof(y) == sizeof(void*) );
|
---|
43 | }
|
---|
44 | f(0,0);
|
---|
45 |
|
---|
46 |
|
---|
47 |
|
---|
48 |
|
---|
49 |
|
---|
50 |
|
---|
51 |
|
---|
52 |
|
---|
53 |
|
---|
54 |
|
---|
55 |
|
---|
56 |
|
---|
57 |
|
---|
58 |
|
---|
59 |
|
---|
60 | // reusing local var `float a[10];`
|
---|
61 | float v;
|
---|
62 | f( a, a ); // ok: two decays, one into an array spelling
|
---|
63 | f( &v, &v ); // ok: no decays; a non-array passes to an array spelling
|
---|
64 |
|
---|
65 |
|
---|
66 |
|
---|
67 |
|
---|
68 |
|
---|
69 |
|
---|
70 |
|
---|
71 |
|
---|
72 |
|
---|
73 |
|
---|
74 |
|
---|
75 |
|
---|
76 |
|
---|
77 |
|
---|
78 |
|
---|
79 |
|
---|
80 | char ca[] = "hello"; // array on stack, initialized from read-only data
|
---|
81 | char *cp = "hello"; // pointer to read-only data [decay here]
|
---|
82 | void edit(char c[]) { // param is pointer
|
---|
83 | c[3] = 'p';
|
---|
84 | }
|
---|
85 | edit(ca); // ok [decay here]
|
---|
86 | edit(cp); // Segmentation fault
|
---|
87 | edit("hello"); // Segmentation fault [decay here]
|
---|
88 |
|
---|
89 |
|
---|
90 |
|
---|
91 |
|
---|
92 |
|
---|
93 |
|
---|
94 |
|
---|
95 |
|
---|
96 |
|
---|
97 |
|
---|
98 |
|
---|
99 |
|
---|
100 | void decay( float x[10] ) {
|
---|
101 | static_assert( sizeof(x) == sizeof(void*) );
|
---|
102 | }
|
---|
103 | static_assert( sizeof(a) == 10 * sizeof(float) );
|
---|
104 | decay(a);
|
---|
105 |
|
---|
106 | void no_decay( float (*px)[10] ) {
|
---|
107 | static_assert( sizeof(*px) == 10 * sizeof(float) );
|
---|
108 | }
|
---|
109 | static_assert( sizeof(*pa) == 10 * sizeof(float) );
|
---|
110 | no_decay(pa);
|
---|
111 | }
|
---|