Добрый день,
вопрос в следующем: есть некоторая архитектура похожая на COM. В ней есть базовый интерфейс, от которого наследуются другие интерфейсы:
struct IBaseInterface
{
virtual uint32_t AddRef() = 0;
virtual uint32_t Release() = 0;
virtual int QueryInterface(uint32_t id, void** object) = 0;
};
Проблема заключается в том, что если взять даже такую простую функцию
inline uint32_t GetReferenceCount(IBaseInterface *obj)
{
uint32_t ref = obj->AddRef();
obj->Release();
return ref - 1;
}
Компилятор захочет вставить в место инлайна этой функции SEH-фрейм, по причине того, что он предполагает что функции AddRef и Release могут кидать исключения. Особенно досадно это видеть в деструкторах, которые делают Release для интерфейсов. Добавив в пару широко используемых функций (например в smart pointer, который делает в конструкторе AddRef, а в деструкторе Release), спецификатор __declspec(nothrow) (этот спецификатор убирает SEH-фрейм в данной функции и считает, что эта функция не кидает исключения) я получил существенный выигрыш по объему сгенерированного кода (модуль размером 2.7 мб уменьшился на 6%). Но писать этот спецификатор по месту использования не слишком рационально, хотелось бы пометить сами интерфейсы как не кидающие.
Попробовал несколько способов достижения желаемого эффекта, но они меня все не удовлетворили. Перечислю их ниже (для простоты я оставил только метод Release):
Этот код не приносит ожидаемого эффекта. MSVC все равно думает, что этот метод может кинуть.
struct IBaseInterface
{
__declspec(nothrow) virtual uint32_t Release() = 0;
};
Этот код аналогичен предыдущему и необходимый эффект не достигается.
struct IBaseInterface
{
virtual uint32_t Release() throw() = 0;
};
Т.к. MSVC считает (если компилировать с флагом /EHsc), что функции, объявленные как extern "C" никогда не кидают, была сделана попытка поместить интерфейс в extern "C". Но требуемого поведения, все равно не получилось достигнуть.
extern "C"
{
struct IBaseInterface
{
virtual uint32_t Release() = 0;
};
}
Возможно, кто-нибудь знает способ как можно заставить MSVC 10 думать, что виртуальный метод не кидает исключений? Тогда бы он догадался не делать лишние SEH-фреймы и стал бы лучше генерировать код.
Спасибо.