This is the mail archive of the
mailing list for the glibc project.
Re: [PATCH] Fix aliasing violation tst-rec-dlopen
- From: Zack Weinberg <zackw at panix dot com>
- To: Pedro Alves <palves at redhat dot com>
- Cc: Florian Weimer <fweimer at redhat dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Date: Tue, 15 Dec 2015 10:30:58 -0500
- Subject: Re: [PATCH] Fix aliasing violation tst-rec-dlopen
- Authentication-results: sourceware.org; auth=none
- References: <566FE225 dot 8020208 at redhat dot com> <56702B7D dot 4040109 at redhat dot com> <20151215150434 dot GU11489 at vapier dot lan> <56702E3E dot 4050405 at redhat dot com>
On Tue, Dec 15, 2015 at 10:14 AM, Pedro Alves <email@example.com> wrote:
> /* According to the ISO C standard, casting between function
> pointers and 'void *', as done above, produces undefined results.
> POSIX.1-2003 and POSIX.1-2008 accepted this state of affairs and
> proposed the following workaround:
> *(void **) (&cosine) = dlsym(handle, "cos");
> This (clumsy) cast conforms with the ISO C standard and will
> avoid any compiler warnings.
This construct is *not* conforming; this is a common and understandable
error. `cosine` has a declared type, therefore writing to it via a pointer of
any other (incompatible) type (except `char *`, which is a special case)
provokes undefined behavior.
The only ways a s.c. program can write the value returned by `dlsym` into
a function-pointer variable are with `memcpy` or a union. But in both cases,
then *calling the function pointer* provokes undefined behavior. This is all
very much intentional -- ISO C wants to allow for the possibility that function
pointers are genuinely different in some way from object pointers.
POSIX assumes an architecture where object and function pointers
are interconvertible, and ...
> The 2013 Technical Corrigendum to POSIX.1-2008 (a.k.a.
> POSIX.1-2013) improved matters by requiring that conforming
> implementations support casting 'void *' to a function pointer.
... that was the correct thing for them to do, and the right way to write
this program is just to use a cast.