Skip to content

Fix issues with Windows and the Interconnect library #51

Description

@mosra

Currently, in case two signals have the same signature (such as the StateMachine::stepped() templated signal or Ui::UserInterface::inputWidgetFocused() and inputWidgetBlurred() pair of signals, MSVC merges them in Release mode when the /OPT:ICF flag is enabled as their codegen is the same. That's very unfortunate and leads to nasty hard-to-prevent bugs.

Presently, there are the following options, none of which is ideal:

  1. Manually make each signal generate a different codegen by writing a different value to an internal member. That's how it's done now, is eww and doable only in library code -- we can't force the users to do the same with their emitter implementations.
  2. Globally enable /OPT:NOICF. That'll prevent some useful optimizations elsewhere and again needs to be done by the users as CMake < 3.13 doesn't support INTERFACE_LINK_OPTIONS. Even with CMake 3.13, users with custom buildsystems will have issues because this flag won't get enabled for them automatically. (Note: it might be useful to say /OPT:REF,NOICF instead (source).)
  3. Work around this issue by changing the emit() API. One idea I have is to replace it with a CORRADE_EMIT() macro that has __COUNTER__ inside, which then will get saved to an internal member of the Emitter class. This won't solve it for templated signals, though -- the user would again need to create a unique numeric identifier for these (typeid? something?).
  4. Maybe we can trick the optimizer into thinking the functions are different. Maybe sneaking a printf() inside emit() would work? Some inline assembly?
  5. Maybe some special attributes could cause the function to not be affected by this optimization? (I couldn't find any.)
  6. Hope MSVC fixes this in the linker somehow (they know about it). Though that might not ever happen and even after that we need to stay compatible with previous releases.

In total, there are the following Windows-specific issues:

  • Signals on classes with virtual inheritance have unexpectedly large size on 32-bit (fixed in b83c116)
  • The above /OPT:ICF issue
  • Signals in classes with multiple inheritance work only when the bases are virtual (might help casting the signal pointer to an unknown type to expand it to its full size)
  • Signal with multiple inheritance don't seem to work at all on MinGW, even with the virtual workaround can't reproduce

Metadata

Metadata

Assignees

Projects

Status
Done

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions