Does clang think I need to point to a "const function"?

Viewed 159

GodBolt

Consider the following code snippet:

using A = void(*)(int);

A foo(const void* ptr) 
{
    return reinterpret_cast<A>(ptr);
}

GCC 10 likes this just fine. clang++-10, however, says this is an error!

<source>:5:12: error: reinterpret_cast from 'const void *' to 'A' (aka 'void
 (*)(int)') casts away qualifiers

    return reinterpret_cast<A>(ptr);

           ^~~~~~~~~~~~~~~~~~~~~~~~

Functions aren't mutable in C++ (and C), and there are no "const functions". So why is clang++ complaining here?

2 Answers

Because the standard says so.

[expr.reinterpret.cast]/2:

The reinterpret_­cast operator shall not cast away constness.

[expr.const.cast]/7:

A conversion from a type T1 to a type T2 casts away constness if T1 and T2 are different, there is a cv-decomposition of T1 yielding n such that T2 has a cv-decomposition of the form CV-decomposition of T2

and there is no qualification conversion that converts T1 to CV-decomposition of T1

Here T1 is const void*, T2 is void (*)(int), n = 1, the cv-decomposition of T2 has cv0 = "", P0 = "pointer to", cv1 = "", U2 = void(int), so the corresponding version of T1 is void*. There is no qualification conversion from const void* to void*. It follows that the conversion casts away constness and cannot be performed by reinterpret_cast.

Alert this is not producion friendly code !

using A = void(*)(int);

A foo(const void* ptr)
{
    union McGayver {
         const void* ptr;
         A a;
    } u;
    u.ptr = ptr;
    return u.a;
}

https://godbolt.org/z/1e1oE6

Related