This is the mail archive of the
libc-alpha@sourceware.org
mailing list for the glibc project.
Re: [PATCH] Fix aliasing violation tst-rec-dlopen
- From: Pedro Alves <palves at redhat dot com>
- To: Zack Weinberg <zackw at panix dot com>
- Cc: Florian Weimer <fweimer at redhat dot com>, GNU C Library <libc-alpha at sourceware dot org>
- Date: Tue, 15 Dec 2015 16:12:46 +0000
- 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> <CAKCAbMjJw1-JDMA_KX08+Q3A4hvYWbGXsqk2jGkUVOYz=uzLYQ at mail dot gmail dot com>
On 12/15/2015 03:30 PM, Zack Weinberg wrote:
> On Tue, Dec 15, 2015 at 10:14 AM, Pedro Alves <palves@redhat.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.
>
Right, I'm aware, having gone through fixing a bunch of aliasing warnings
in the past. The point was simply to point out that the way it was written
was following a guideline.
> 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.
(this is not s.c., though.)
Seems like a funny situation: old POSIX suggested A (weird cast)
to avoid warnings emitted if you do the more natural B (pointer conversion).
New POSIX requires that doing B works. Older compilers warned about B.
New compilers warn with A.
As this seems to leave you with no way to avoid the warning everywhere,
I wondered whether specific code in the compiler that was supposed
to suppress the warning in this particular case happened to bit rot
(if it ever existed). I don't recall the last time I saw GCC warn
about B though, truth be told. So maybe not a useful question...
Thanks,
Pedro Alves