This matters when sizeof is directly used in arithmetic, ala "uintptr_t t; t &= -sizeof(long)" (for alignment). When sizeof isn't size_t (as it's specified to be) this masking will truncate the high bits of the uintptr_t object (if uintptr_t is larger than uint).
Showing the changes to tests (1 of 4 files). Show all
Unified · Split
| @@ -2155,6 +2155,8 @@ void c99_vla_test(int size1, int size2) · 2154 unmodified lines | |||
| 2155 | #endif | 2155 | #endif |
| 2156 | } | 2156 | } |
| 2157 | 2157 | ||
| 2158 | typedef __SIZE_TYPE__ uintptr_t; | ||
| 2159 | |||
| 2158 | void sizeof_test(void) | 2160 | void sizeof_test(void) |
| 2159 | { | 2161 | { |
| 2160 | int a; | 2162 | int a; |
| @@ -2175,6 +2177,20 @@ void sizeof_test(void) · 14 unmodified lines | |||
| 2175 | ptr = NULL; | 2177 | ptr = NULL; |
| 2176 | printf("sizeof(**ptr) = %d\n", sizeof (**ptr)); | 2178 | printf("sizeof(**ptr) = %d\n", sizeof (**ptr)); |
| 2177 | 2179 | ||
| 2180 | /* The type of sizeof should be as large as a pointer, actually | ||
| 2181 | it should be size_t. */ | ||
| 2182 | printf("sizeof(sizeof(int) = %d\n", sizeof(sizeof(int))); | ||
| 2183 | uintptr_t t = 1; | ||
| 2184 | uintptr_t t2; | ||
| 2185 | /* Effectively <<32, but defined also on 32bit machines. */ | ||
| 2186 | t <<= 16; | ||
| 2187 | t <<= 16; | ||
| 2188 | t++; | ||
| 2189 | /* This checks that sizeof really can be used to manipulate | ||
| 2190 | uintptr_t objects, without truncation. */ | ||
| 2191 | t2 = t & -sizeof(uintptr_t); | ||
| 2192 | printf ("%lu %lu\n", t, t2); | ||
| 2193 | |||
| 2178 | /* some alignof tests */ | 2194 | /* some alignof tests */ |
| 2179 | printf("__alignof__(int) = %d\n", __alignof__(int)); | 2195 | printf("__alignof__(int) = %d\n", __alignof__(int)); |
| 2180 | printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); | 2196 | printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); |