Ensure existence of required channel constructor (only MSVC)

Declaring constructor = default was allowing aggressive optimization.
Compiler would skip both channel registration, and static asserts.
dependabot/npm_and_yarn/Src/WebController/UI/websocket-extensions-0.1.4
Pawel Kurowski 2020-02-28 10:59:23 +01:00
parent 91dc3a1163
commit bae365b02c
1 changed files with 5 additions and 3 deletions

View File

@ -11,13 +11,16 @@ namespace MWR::C3
template <typename Iface, typename AbstractType, HashT clousureConnectorHash = 0> template <typename Iface, typename AbstractType, HashT clousureConnectorHash = 0>
struct Register : AbstractType struct Register : AbstractType
{ {
Register() virtual ~Register()
{ {
// Addressing variable in constructor prevents compiler from skipping template instantiation, because of possible side effects. // Addressing variable in virtual destructor prevents compiler from skipping template instantiation, because of possible side effects.
// Similar effect can be achieved in gcc with attribute 'used'
// Clang can ignore both approaches, if Iface does not declare any custom constructor.
static_cast<void>(m_Registered); static_cast<void>(m_Registered);
static_cast<void>(s_InterfaceHash); static_cast<void>(s_InterfaceHash);
} }
private:
/// Main function responsible for registration of interface. /// Main function responsible for registration of interface.
/// Return value of function is used to initialize static variable assuring execution of code before main. /// Return value of function is used to initialize static variable assuring execution of code before main.
/// @returns true. /// @returns true.
@ -27,7 +30,6 @@ namespace MWR::C3
return InterfaceFactory::Instance().Register<AbstractType>(Iface::s_InterfaceHash, CreateInterfaceData()); return InterfaceFactory::Instance().Register<AbstractType>(Iface::s_InterfaceHash, CreateInterfaceData());
} }
private:
template <typename T> template <typename T>
class EnsureDefaultCapability class EnsureDefaultCapability
{ {