> ==================================== foo.c > ==================================== > #include <stddef.h> > #include <stdlib.h> > #ifdef __GNUC__ > # define unreachable() __builtin_unreachable () > #endif > typedef struct { int a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t; } foo; > int main () > { > char *m = malloc (1); > if (m == NULL) > unreachable (); > foo *p = (foo *) m; /* CAST */ > ptrdiff_t d = p - p; /* DIFFERENCE */ > foo *q = p + 0; /* ADDITION */ > free (m); > } > /* gcc > -fsanitize=address,undefined,signed-integer-overflow,shift,integer-divide-by-zero > foo.c */ > /* clang > -fsanitize=address,undefined,signed-integer-overflow,shift,integer-divide-by-zero > foo.c */ > =============================================================================== > > gcc's and clang's sanitizers let this program pass at runtime. > > The line /* CAST */ is probably OK because ISO C 23 § 6.5.4 specifies no > undefined behaviour.
This line is not guaranteed to be ok due to § 6.3.2.3, (7): A pointer to an object type may be converted to a pointer to a different object type. If the resulting pointer is not correctly aligned for the referenced type, the behaviour is undefined. alignof(char) will be 1 and the alignment of foo will probably be 4, hence there is no guarantee that the pointer value of p is properly aligned. You have just the exception that you are free to convert a (foo *) to (char *) and to even convert a (char *) back to (foo *) if it was originally a (foo *). See also § 6.2.5, (33) according to which pointers to structure types (as foo in the example) can have possibly a different representation than a pointer to char. To see the problem, assume a word addressed machine where char pointers need extra representation for the byte offset within a word. How could you convert a non-word-aligned (char *) to a (foo *) on such a machine? Andreas. -- Dr. Andreas F. Borchert, Institut für Numerische Mathematik, Universität Ulm Helmholtzstr. 20, 89081 Ulm, +49 7315023572 https://mathematik.uni-ulm.de/afb
smime.p7s
Description: S/MIME cryptographic signature