Date: Wed, 26 Apr 2023 16:19:26 -0700
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.
I mentioned this some years ago as a possible defect report, and I sent a
request for one, but it never got filed.
Should something like this be a defect report? What is the correct
interpretation of the Standard on this? Being a conditionally supported
operation, is either interpretation allowed?
[expr.reinterpret.cast]/2 <https://eel.is/c++draft/expr.reinterpret.cast#2>
says that reinterpret_cast "shall not cast away constness". But is casting
to function pointer type removing constness? [expr.reinterpret.cast]/8
<https://eel.is/c++draft/expr.reinterpret.cast#8> mentions the possibility
of cv-qualified casts in the other direction.
Function types have no cv qualification in the normal sense. A
cv-qualified member function is referring to the "this" parameter, not the
constness of the function itself. Is a cast to function type removing a cv
qualifier when functions having them is nonsensical to begin with?
#include <cstdint>
#include <cstdio>
#if !defined(__x86_64__) && !defined(_M_X64)
#error "This is an x86-64-only program"
#endif
#ifdef _MSC_VER
#pragma code_seg(push, ".text")
#pragma code_seg(pop)
#define EXECUTABLE_SEGMENT __declspec(allocate(".text"))
#elif defined(__linux__)
#define EXECUTABLE_SEGMENT [[gnu::section(".text.meow")]]
#else
#error "Unknown platform"
#endif
// movl $0x12345678, %eax
// ret
EXECUTABLE_SEGMENT const std::uint8_t s_code[] =
{
0xB8, 0x78, 0x56, 0x34, 0x12, 0xC3
};
int main()
{
// an intervening std::uintptr_t cast works with all compilers relevant
here
int result = reinterpret_cast<int (*)()>(s_code)();
std::printf("%08X\n", result);
return 0;
}
Melissa
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.
I mentioned this some years ago as a possible defect report, and I sent a
request for one, but it never got filed.
Should something like this be a defect report? What is the correct
interpretation of the Standard on this? Being a conditionally supported
operation, is either interpretation allowed?
[expr.reinterpret.cast]/2 <https://eel.is/c++draft/expr.reinterpret.cast#2>
says that reinterpret_cast "shall not cast away constness". But is casting
to function pointer type removing constness? [expr.reinterpret.cast]/8
<https://eel.is/c++draft/expr.reinterpret.cast#8> mentions the possibility
of cv-qualified casts in the other direction.
Function types have no cv qualification in the normal sense. A
cv-qualified member function is referring to the "this" parameter, not the
constness of the function itself. Is a cast to function type removing a cv
qualifier when functions having them is nonsensical to begin with?
#include <cstdint>
#include <cstdio>
#if !defined(__x86_64__) && !defined(_M_X64)
#error "This is an x86-64-only program"
#endif
#ifdef _MSC_VER
#pragma code_seg(push, ".text")
#pragma code_seg(pop)
#define EXECUTABLE_SEGMENT __declspec(allocate(".text"))
#elif defined(__linux__)
#define EXECUTABLE_SEGMENT [[gnu::section(".text.meow")]]
#else
#error "Unknown platform"
#endif
// movl $0x12345678, %eax
// ret
EXECUTABLE_SEGMENT const std::uint8_t s_code[] =
{
0xB8, 0x78, 0x56, 0x34, 0x12, 0xC3
};
int main()
{
// an intervening std::uintptr_t cast works with all compilers relevant
here
int result = reinterpret_cast<int (*)()>(s_code)();
std::printf("%08X\n", result);
return 0;
}
Melissa
Received on 2023-04-26 23:19:39