#cpp #cpp11
Задача: получить и преобразовать адрес функции. Смысл подразумевается следующий:
Имеем функцию
void func() {}; // имеем адрес 0x500000, к примеру
constexpr size_t inc_pointer = to_size_t(&func) + 5; // (*)
Где to_size_t - это макрос/constexpr функция, которая преобразует адрес функции в
число на этапе компиляции. Реализация может быть следующая:
#define to_size_t(x) (size_t)(x) // C-style каст
#define to_size_t(x) reinterpret_cast(x) // C++-style каст
Почему я не написал cast сразу будет понятно ниже.
Проблема в том, что конструкция (*) превращается в следующий код
mov eax, 0x500000 // 0x500000 == адрес функции func
add eax, 5
...
Я же хочу добиться того, чтобы код был
mov eax, 0x500005
...
Попытка 1
Сast'ы ни к чему хорошему не привели, результат выше
Попытка 2
template union converter
{
T _func;
size_t _pointer;
constexpr converter(T func) : _func(func) {};
};
#define to_size_t(x) converter{x}._pointer
#define identity(x) converter{x}._value
Для проверки constexpr'a я пользуюсь следующей функций:
template void print_it() { std::cout << N << std::endl; }
Загвоздка в том, что constexpr union не хочет работать так, как мне нужно
print_it(); // ок, компилируется (обращение к полю _value)
print_it(); // error C2975: 'N': invalid template argument for 'print_it',
expected compile-time constant expression
Выслушаю ваши идеи.
P.S. А следующий код вообще крашит студию (2015-ю)
template constexpr T identity_constexpr(T value) { return value; }
print>(); // fatal error C1001: An internal error has occurred
in the compiler.
UPDATE
Ответ получен, видимо проблему придётся решать, заменяя конструкции соответствующим
образом уже после компиляции в готовом исполняемом файле.
Ответы
Ответ 1
Всякий раз программа, вообще говоря, загружается в разное место в памяти - как тут можно говорить об адресе на уровне компиляции? Максимум, что можно (теоретически!) получить, и то на уровне компоновки - это относительное смещение адресов.Ответ 2
Чисто предположения ради: попробовать распихать функции по разным секциям, а вот секциям задать адреса и размер через скрипт линковщика. Границы можно объявить экстерном и constexpr, тем самым обеспечив доступ к нужно информации на этапе компиляции. Может даже что-то выйти.
Комментариев нет:
Отправить комментарий