Я разработчик C ++ с некоторого времени, но я не использовал много указателей на функции-члены.Я нашел уже несколько опасных сценариев при использовании таких указателей.Мне нужен коллега с большим опытом, чтобы объяснить это дальше, потому что отладка и анализ не так просты.
Проблема возникает, когда компилятор решает не назначать адрес функции из-за некоторой оптимизации.Со мной это случилось с VS 2015 даже в Debug, x86 (с отключенной оптимизацией - / Od).Я выполняю рефакторинг одной старой системы и перемещаю некоторый код в общую статическую библиотеку (common.lib), чтобы ее можно было использовать из нескольких проектов.Даже если это не лучший шаблон, старая реализация сильно зависит от указателей на функции, поэтому я не хочу менять это сейчас.Например, я добавил интерфейс ModuleBase к одному очень большому старому классу в нечто вроде:
class ModuleBase
{
public:
typedef void (ModuleBase::*Main)() const; // moved from old module
virtual void FunctionMain() const = 0; // Function has no address, possibly due to compiler optimizations.
virtual void FunctionSecondary() const = 0; // Function has no address, possibly due to compiler optimizations.
};
class OldModule : public ModuleBase
{
public:
virtual void FunctionMain() const {};
virtual void FunctionSecondary() const {};
}
Идея состояла в том, чтобы переместить ModuleBase в статическую библиотеку, но OldModule оставить в основном проекте EXE.Пока ModuleBase был в основном проекте, он работал нормально, но когда я перемещал его в статический Common.lib, он начинал падать!У меня ушло около 2 дней, чтобы наконец заметить, что в нескольких местах компилятор решил (но только для статической библиотеки) не назначать адреса FunctionMain, FunctionSecondary () и т. Д. Из ModuleBase.Поэтому, когда указатели на эти виртуальные функции были переданы другим подпрограммам, они были нулями.
Например, в приведенном ниже коде:
new Manager::ModuleDecription(
"Test Module",
"Secondary Scene",
"Description"
PosX,
PosY,
Proc,
&ModuleBase::FunctionSecondary //contains nullptr when in static library!!!!!
Последний член в структуре был нулевым, но только в статической библиотеке.Это было довольно неприятно, потому что мне пришлось проверить много других вещей, прежде чем это заметить.Также есть другие указатели, которые не были нулевыми, потому что структура не была обнулена в конструкторе, поэтому нужно заметить, что значение адреса отличается и вылетает при попытке вызвать функцию.
Итак, мои вопросы - 1)Правильно ли я вижу это - это допустимая ситуация (компилятор удаляет адреса функций в приведенном выше случае для того же кода, но при перемещении в статическую библиотеку)?
2) Как заставить компилятор всегдасохранить адреса функций-членов?