On Wednesday, 26 April 2023 16:19:26 PDT Myria via Std-Discussion wrote:
> C++ says that reinterpret_casting an object pointer to a function pointer
> is conditionally supported. However, there seems to be implementation
> divergence on what happens if the object pointer is cv-qualified. GCC
> allows casts from cv object * to function pointer, but Clang and Visual C++
> do not.
Hello Myria
WB
I think this should not be considered a defect in the standard. Instead, it
should be a considered a defect in GCC for allowing it, because it allows for
discarding a const qualifier without a const_cast, permitting this:
const void *cptr = &i;
auto fptr = reinterpret_cast<void (*)()>(cptr);
auto ptr = reinterpret_cast<int *>(fptr);
*ptr = 1;
https://gcc.godbolt.org/z/3eWP7866x
(don't ask me what MSVC is doing there)
Perhaps the request should
be editorial to put notes clarifying that this case is ill-formed,
because function types aren't const?
As for
MSVC, I'll look into that one; it may be a compiler bug, or may be a
reaction to undefined behavior (writing to a const object).
I don't think there's any way to get to a standards-bounded situation where
the problem arises in the first place. You always need some level of platform-
specific knowledge.
Within the C++ Standard,
yes. The POSIX Standard does require that void* to function pointer
type work because of dlsym(), but that's also not const.
I just remembered another aspect to this whole thing, though: C-style casts.
If instead of reinterpret_cast, we do this:
int result = ((int (*)()) s_code)();
Clang
and GCC allow it, but MSVC does not. It sounds like MSVC is correct in
considering this ill-formed, because of the definition of C-style casts
(
[expr.cast]/4) :
The conversions performed by
a const_cast
- a static_cast
- a static_cast followed by a const_cast,
- a reinterpret_cast, or
- a reinterpret_cast followed by a const_cast,
can be performed using the cast notation of explicit type conversion.
The C-style cast appears to be
ill-formed because there is no valid reinterpret_cast that would make
this legal even with a const_cast after it. It is counterintuitive that
a C-style cast could be ill-formed due to removing const.
Melissa