5

I have a common problem, and this time, instead of solving it, I would like to understand the benefits of this design choice. I am coming from a solid 15+ years of Linux/C++ development and I have hard time dealing with building applications for Windows.

I have an application which is linking with proprietary components (Intel OneApi and Basler Pylon). I would like to debug my application, but I cannot compile my code in debug mode, because the proprietary components do not provide debug builds for their libraries.

On Linux I am allowed to mix any libraries; Release and Debug. I can even mix libraries built using different compiler versions as long as the ABI does not change between the different versions.

If I cannot build my applications in debug mode on Windows with MSVC, then how am I supposed to debug them?

If the official recommendation is the "just write good code" approach, then what are the incredible benefits of this limitation? Does the library run 2x faster? Does it take 10x less storage space?

The ridiculous part is that MinGW allows mixing debug and release libraries even on Windows, however the proprietary libraries are build with MSVC.

Thank You for Your insight.

user1396055
  • 295
  • 1
  • 12
  • 4
    It *is* possible to debug optimized builds. It's just a lot harder. And you *can* build optimized binaries *with* debug symbols, which makes it a bit less hard. – Jesper Juhl Sep 29 '22 at 12:14
  • Note there is [as-if rule](https://en.cppreference.com/w/cpp/language/as_if), this means that optimizer can do lots of strange transformations to the code. As a result debugging optimized code can be very confusing. – Marek R Sep 29 '22 at 12:19
  • 1
    _"..but I cannot compile my code in debug mode, because the proprietary components do not provide debug builds for their libraries."_ What happens if you do so? – Jabberwocky Sep 29 '22 at 12:20
  • And there are a macros which depend on Debug/Release mode which often alters code flow a bit. – Marek R Sep 29 '22 at 12:22
  • 5
    With MSVC the Standard Library has different ABIs (some structures change size / layout) between debug and release builds. – Richard Critten Sep 29 '22 at 12:25
  • 1
    This might help: https://learn.microsoft.com/en-us/cpp/build/how-to-debug-a-release-build?view=msvc-170 – NathanOliver Sep 29 '22 at 12:27
  • Answer to Jabberwocky bunch of undefined references. – user1396055 Sep 29 '22 at 12:56
  • Answer to NathanOliver I do not want to debug Release Build. I would like to Debug My Code in Debug Build. – user1396055 Sep 29 '22 at 12:57
  • 4
    Question like this always work much better if you describe the build error you see and ask what to do about it. This scenario typically produces a link-time error when the linker can see that the object files were built with incompatible settings. It checks for a match in the compiler major version number and the `_ITERATOR_DEBUG_LEVEL` value, they cause ABI trouble. Set the latter to 0. And verifies that the same runtime library gets used, having multiple copies of them in a single process rarely ends well, too much global state. C/C++ > Code Generation > Runtime Library = /MD – Hans Passant Sep 29 '22 at 13:12

1 Answers1

0

The ABI of STL is different between Release- and Debug-mode under MSVC. One category of difference is additional private members in types under Debug mode, to add various run-time checks and metadata. But there are also other categories of differences. (example)

I wouldn't even expect my own types to be ABI-compatible between Release and Debug mode under MSVC, unless I finely controlled the layout with a bunch of #pragmas (and of course used no STL in my headers). This is because I expect the designers of MSVC make no effort to make Debug- and Release-mode builds ABI compatible, because they've already thoroughly broken compatibility for STL.

I'm surprised to hear your report that this is not also the case under whatever compilers you used under Linux. Among C++ MSVC users like me, the understanding is that half the point of a Debug build is the extra run-time checks and metadata. Maybe you were talking about C binaries, or about C++ binaries with extern "C" interfaces -- both of which IIRC are more common on Linux than binaries with a C++ ABI? (Even the latter will explode at run-time when mixed with binaries of the other mode, of course, if you are sending STL types over opaque pointers or some other attempted workaround.)

As you are probably aware, you cannot safely link binaries with a C++ ABI produced by different toolchains -- even different versions of the same toolchain -- unless the toolchain vendor explicitly says otherwise. This is because the details of how e.g. a function call works at the level of layout and machine instruction have never been conventionalized for C++ like it has for C. This is why:

  • C is the lingua franca of native programming
  • Publishers of C++ binaries often give them a C ABI via extern "C".

So then, the reason for my surprise at your question is, if you are looking at a binary with a C++ ABI, typically you:

  • already have access to its source code and can easily produce a new build under whatever mode you need (e.g. open-source, or your own binaries); or
  • the publisher has published both Release- and Debug-mode versions of its binaries, often for multiple versions of multiple toolchains (e.g. Qt).

The only exceptions I have seen to this have been in the engineering industry -- I remember Siemens published some fancy CAD software, and you were simply required to use the same major-ish version of MSVC they used, which meant you had to upgrade to a newer version of their software when you upgraded to a new version of MSVC, and vice-versa.

Keith Russell
  • 560
  • 4
  • 12