[cfe-dev] The %p conversion and cast to void*

Seth Cantrell seth.cantrell at gmail.com
Wed Feb 25 07:03:20 PST 2015


> On Feb 25, 2015, at 3:43 AM, David Chisnall <David.Chisnall at cl.cam.ac.uk> wrote:
> 
> On 24 Feb 2015, at 22:38, Seth Cantrell <seth.cantrell at gmail.com> wrote:
>> 
>> Depends on how you define 'bug'. I include most kinds of undefined behavior, and if I came upon this warning in any of my code during everyday development I would fix it.
> 
> This is not undefined behaviour, it is implementation-defined behaviour, and it is implementation-defined behaviour that is shared across all vaguely modern C implementations, including some quite exotic ones.

Are you sure? My copy of the C99 spec says "• If any argument is not the correct type for the corresponding conversion specification, the behavior is undefined." [7.19.6.1p9] and the conversion specification 'p' is specified with "The argument shall be a pointer to void." The C11 draft I have says the same.

I understand there may be more to it than that and that I may have missed something somewhere else which turns this into implementation defined behavior, but as it stands it does look to me like undefined behavior. So I think that accepting other types of pointers would qualify as a conforming extension rather than implementation defined behavior.

> The 'fix' for the warning clutters the code and makes it less readable.  People reading the code will wonder why you're casting the value to a pointer, when they thought it was already a pointer.

It's a simple cast to void*, and they ought to understand that pointers can have different types and why one might cast between types. They'll learn exactly why if they try to remove the cast and start getting a diagnostic.

> Having a warning if you pass a function pointer as the parameter for %p (which we currently lack) would be entirely sensible, as there *are* platforms with C implementations where data pointer and function pointer representations differ and the C standard makes no guarantee that these will work - though this warning might be silenced in POSIX mode, as POSIX relies on the ability to cast void* to a function pointer.

I agree; converting between data and function pointers is either undefined behavior or an optionally supported feature, depending on the spec. Having flags to catch that is similarly worthwhile.

>   Having a warning for something that:
> 
> - Works on every current implementation
> - Is used by so much code that no future implementation can safely break it
> 
> is a complete waste of everyone's time.
> 
> David

I see value in both flagging undefined behavior and in the ability to turn off extensions.

If you want a practical benefit: gcc has this warning, which may be converted to an error. Users developing under clang may prefer to catch this earlier so that it doesn't show up at a later time when the code is compiled under gcc with -Wall -Wextra -pedantic -Werror.



More information about the cfe-dev mailing list