This is the mail archive of the
newlib@sourceware.org
mailing list for the newlib project.
Re: Strict aliasing and malloc
- From: Brian Inglis <Brian dot Inglis at SystematicSw dot ab dot ca>
- To: newlib at sourceware dot org
- Date: Tue, 3 Jul 2018 12:07:11 -0600
- Subject: Re: Strict aliasing and malloc
- References: <CADekCYGGXfAbW5S1J_WkaOHm30L=BzKtw0N3zFvGZNA8Pkyg3w@mail.gmail.com>
- Reply-to: Brian dot Inglis at SystematicSw dot ab dot ca
On 2018-07-03 09:16, narwhal x wrote:
> Hello,
>
> I have a question regarding newlib and the -fstrict-aliasing implied
> by turning on O2.
>
> The strict aliasing implied by the ISO standard and enabled in gcc
> with O2 (This might be specific to gcc, but could be the case with any
> compiler with aliasing optimizations) makes it so you can only cast a
> pointer to a compatible type, and a special case is malloc, which
> should return an "undeclared type" *.
>
> I however did not find the -fno-strict-aliasing flag in any
> configuration or makefile (If I just overlooked it, and the flag is
> mandatory that would answer my question)
>
> My question:
> In newlib/libc/stdlib/mallocr.c on line 2212 you have the statement:
> "top = (mchunkptr)brk;"
> Here top is of type "mchunkptr" and brk is a "char *". The standard
> says that you can not just alias a incompatible type and dereference
> it (unless it's a malloc'ed variable, as it would change it's type
> when written to, but how do you inform the compiler?)
>
> As an example, see 4.2.1 (p. 63) in
> https://www.cl.cam.ac.uk/~pes20/cerberus/notes30.pdf
>
> So is this allowed? Or am I missing something.
>
> * After asking in the gcc IRC, they mentioned that the way they go
> about having the special case for malloc is making sure the libc
> library is linked from a library and no LTO is performed.
>
>
> My main reason for asking is just wanting to know how a malloc
> implementation should deal with these restrictions stated by the ISO C
> standard, and improve my understanding of the (sometimes confusing)
> aliasing rules.
Pointer types char * and void * can be converted to other data pointer types,
and character types can alias other types, but you should not alias objects via
casts or conversions of pointers to objects stored as incompatible types,
because optimization could eliminate the stores, so the underlying storage of
the object of incompatible type may not be updated, and the compiler would not
know that because the type is different, as the compiler does not track possible
aliasing of incompatible types. Roughly IMHO HTH YMMV ;^>
Implementations of malloc use char * internally and convert those to char ** and
int * to maintain their internal housekeeping data at the start of the block,
often using unions, returning a pointer to universally aligned storage following
that block prefix, often resulting in malloc overhead of one or more universally
aligned blocks per allocation; reducing space overhead takes more work: see e.g.
https://sourceware.org/git/?p=newlib-cygwin.git;a=blob;f=newlib/libc/stdlib/mallocr.c;h=ecc445f3d36365a4840e31c737db5018ddba42e9;hb=8e732f7f7f684f22b283f39a5d407375b3b0b3af
--
Take care. Thanks, Brian Inglis, Calgary, Alberta, Canada