RFR (S): 8151322: Implement os::set_native_thread_name() on Solaris
David Holmes
david.holmes at oracle.com
Tue Mar 22 04:13:49 UTC 2016
On 22/03/2016 1:21 PM, Kim Barrett wrote:
>> On Mar 21, 2016, at 8:00 PM, David Holmes <david.holmes at oracle.com> wrote:
>>>
>>> reinterpret_cast (and all the C-style casts involved are really
>>> reinterpret_casts) can be used to convert a function pointer to a
>>> different function pointer type. It can also be used to convert
>>> between any pointer (including function pointers) and (appropriate)
>>> integer types. No other conversions involving function pointers are
>>> allowed. (C++11 adds "Converting a function pointer to an object
>>> pointer type or vice versa is conditionally-supported.")
>>>
>>> Since void* is not a function pointer type, there's no specified
>>> direct conversion from a void* to a function pointer. That's the
>>> raison d'etre for CAST_TO_FN_PTR. (Although conversion to an integer
>>> then to some other type (not back to the original type) and then use
>>> is implementation-defined.)
>>>
>>> However, it seems that some compilers (including the Solaris versions
>>> we've been using) allow direct void* -> function pointer conversions.
>>
>> I thought any pointer type could be converted to void* and back again?
>
> Only for object pointers, not for function pointers.
Ah!
> Note, however, that the POSIX description of dlsym says (in the non-normative “Application Usage” section):
>
> Note that conversion from a void * pointer to a function pointer as in:
>
> fptr = (int (*)(int))dlsym(handle, "my_function");
>
> is not defined by the ISO C standard. This standard requires this conversion to work correctly on conforming implementations.
>
> I only noticed this today. So maybe CAST_TO_FN_PTR is not needed in Unix/POSIX-specific code?
You pre-empted my next question: given dlsym returns void* and has to be
converted to a function ptr there would have to be some legal way to
achieve this. :) Kind of interesting though that POSIX puts an
obligation on the compiler writer.
Looking at the C standard, given any function-ptr can be converted to
another type of function-ptr and back without change, it seems to me
that the return type of dlsym (and related library calls) should be
void(*)(void) to be strictly correct wrt the language standards. But in
practice as long as pointers are all the same size (which seems the
obvious and common implementation [ but by no means guaranteed ]) then
the conversion works correctly with no actual changes to the bits.
> Unfortunately, the description of CAST_TO_FN_PTR is kind of vague, so it’s unclear who the culprit(s) that led to it might be. It would be easy enough to simplify the macro definition and see if any currently supported compilers complain. And there are only 136 occurrences to clean up if that becomes a thing to do.
The comment seems clear enough, though without naming problematic compilers:
//
// ANSI C++ does not allow casting from one pointer type to a function
pointer
// directly without at best a warning. This macro accomplishes it silently
// In every case that is present at this point the value be cast is a
pointer
// to a C linkage function. In some case the type used for the cast reflects
// that linkage and a picky compiler would not complain. In other cases
because
// there is no convenient place to place a typedef with extern C linkage
(i.e
// a platform dependent header file) it doesn't. At this point no
compiler seems
// picky enough to catch these instances (which are few). It is possible
that
// using templates could fix these for all cases. This use of templates
is likely
// so far from the middle of the road that it is likely to be problematic in
// many C++ compilers.
//
but that dates back to pre-1999 so ... :)
In any case it seems CAST_TO_FN_PTR is really for shared code and in
platform specific code we should know whether supported compilers have
an issue or not. Of course it would have been better to have been
consistent about this throughout the codebase, but when writing
platform-specific code it is rarely obvious when something like
CAST_TO_FN_PTR is needed, if the "obvious" coding pattern works.
Just for fun I'll do a JPRT run to see if anything complains if
CAST_TO_FN_PTR(type,val) simply does ((type)(val)).
Cheers,
David
More information about the hotspot-runtime-dev
mailing list