#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, тем самым обеспечив доступ к нужно информации на этапе компиляции. Может даже что-то выйти.
Комментариев нет:
Отправить комментарий