Страницы

Поиск по вопросам

пятница, 1 февраля 2019 г.

Адрес функции на этапе компиляции

Задача: получить и преобразовать адрес функции. Смысл подразумевается следующий:
Имеем функцию
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
Ответ получен, видимо проблему придётся решать, заменяя конструкции соответствующим образом уже после компиляции в готовом исполняемом файле.


Ответ

Всякий раз программа, вообще говоря, загружается в разное место в памяти - как тут можно говорить об адресе на уровне компиляции?
Максимум, что можно (теоретически!) получить, и то на уровне компоновки - это относительное смещение адресов.

Комментариев нет:

Отправить комментарий