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 | 2155 | #endif |
| 2156 | 2156 | } |
| 2157 | 2157 | |
| 2158 | +typedef __SIZE_TYPE__ uintptr_t; | |
| 2159 | + | |
| 2158 | 2160 | void sizeof_test(void) |
| 2159 | 2161 | { |
| 2160 | 2162 | int a; |
| @@ -2175,6 +2177,20 @@ void sizeof_test(void) · 14 unmodified lines | ||
| 2175 | 2177 | ptr = NULL; |
| 2176 | 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 | 2194 | /* some alignof tests */ |
| 2179 | 2195 | printf("__alignof__(int) = %d\n", __alignof__(int)); |
| 2180 | 2196 | printf("__alignof__(unsigned int) = %d\n", __alignof__(unsigned int)); |