GCC предупреждает о функции указателя на приведение указателя объекта

Ясно, что приведение между указателями на функции и указателями на объекты является неопределенным поведением в общем смысле, но POSIX (см .: dlsym) и WinAPI (см .: GetProcAddress) требуют этого.

Учитывая это, и учитывая тот факт, что такой код в любом случае нацелен на специфичный для платформы API, его переносимость на платформы, где указатели функций и указатели объектов несовместимы, на самом деле не имеет значения.

Но -Wpedantic предупреждает об этом в любом случае, и #pragma GCC diagnostic ignored "-Wpedantic" не имеет никакого эффекта:

warning: ISO C++ forbids casting between pointer-to-function and pointer-to-object [enabled by default]

Я хочу сохранить -Wpedantic включен, так как он дает хорошие предупреждения, но я не хочу, чтобы настоящие предупреждения и ошибки терялись в море несущественных предупреждений о указателе функции на приведение указателя объекта.

Есть ли способ сделать это?

Запуск GCC 4.8.0 в Windows (MinGW):

gcc (rubenvb-4.8.0) 4.8.0

ОБРАЗЕЦ КОДА

#include <windows.h>
#include <iostream>int main (void) {

std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"),"five")) << std::endl;

}

Излучает (с -Wpedantic):

warning_demo.cpp: In function 'int main()':
warning_demo.cpp:7:87: warning: ISO C++ forbids casting between pointer-to-funct
ion and pointer-to-object [enabled by default]
std::cout << *reinterpret_cast<int *>(GetProcAddress(LoadLibraryA("test.dll"),
"five")) << std::endl;

^

10

Решение

Я думаю, что вы могли бы использовать g ++ system_header директива здесь:

wrap_GetProcAddress.h:

#ifndef wrap_GetProcAddress_included
#define wrap_GetProcAddress_included

#pragma GCC system_header

template <typename Result>
Result GetProcAddressAs( [normal parameters] )
{
return reinterpret_cast<Result>(GetProcAddressAs( [normal parameters] ));
}

#endif
3

Другие решения

Это отлично работает.

template <typename RESULT, typename ...ARGS>
void * make_void_ptr(RESULT (*p)(ARGS...)) {
static_assert(sizeof(void *) == sizeof(void (*)(void)),
"object pointer and function pointer sizes must equal");
void *q = &p;
return *static_cast<void **>(q);
}
3

Всегда есть трюк с memcpy, который вы можете использовать:

int (*f)() = 0;
int *o;
memcpy(&o, &f, sizeof(int*));

Вы можете увидеть это на ideone: m генерирует предупреждения, в то время как g в порядке.

Что касается других действий, которые вы, возможно, захотите предпринять: одной очевидной возможностью будет «исправить» заголовок, определяющий dlsym на самом деле вернуть указатель на функцию (например, void (*)()). Удачи с этим.

2
По вопросам рекламы [email protected]