C++ Logo

std-discussion

Advanced search

Re: Casts from const object type to function pointer type

From: Myria <myriachan_at_[hidden]>
Date: Thu, 27 Apr 2023 11:46:03 -0700
 On Thu, Apr 27, 2023 at 8:19 AM Thiago Macieira <thiago_at_[hidden]>
wrote:

> 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 <https://eel.is/c++draft/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

Received on 2023-04-27 18:46:21