2

I have a problem that I can't figure out. My project using the OpenEXR library is perfectly working on the Linux platform. It has to be compilable also in Visual Studio 2015. Hence I'm trying to port it. I have successfully compiled and installed OpenEXR 2.2.0 release (downloaded from the official site, following instructions at GitHub). Unfortunately I'm hitting several issues with my code. One of them can be simplified to the following small snippet:

#include <OpenEXR/ImfInputFile.h>
#include <OpenEXR/ImfHeader.h>

int main(int argc, char * argv[]) {

  Imf::InputFile exr_file("test.exr");
  const Imf::Header & exr_header = exr_file.header();

  // e.g. this fails at debug assertion: map/set iterators incompatible
  bool test1 = exr_header.begin() != exr_header.end();

  // or this gets stuck somehow and consuming CPU, the program doesn't continue
  bool test2 = exr_header.begin() != exr_header.begin();

  return 0;
}

When it is compiled in the Release mode it seems to be fine (at least for the snippet, my project has some other issues which I suspect to be related). But in the Debug mode, which I need to debug my project, strange things occur. The first test ends with a debug assertion:

Debug Assertion Failed!

Program: C:\WINDOWS\SYSTEM32\MSVCP140D.dll
File: c:\program files (x86)\microsoft visual studio 14.0\vc\include\xtree
Line: 326

Expression: map/set iterators incompatible

The second one (when the first is commented out) gets stuck and the program seems like to be in an endless loop. I don't understand why.

Please, can somebody help me? I'm using Visual Studio Community 2015 if that matters.

Michal Wirth
  • 169
  • 2
  • 8
  • The debug mode is doing its job. It is telling you there is a bug in your program. Take advantage of this valuable information and fix the issue by debugging your program. The issue is more than likely `exr_header` is invalid. I see no test for validity, and instead you're assuming that the reference is valid. – PaulMcKenzie May 12 '16 at 09:59
  • I know that the file is valid, and is being opened because otherwise an exception would be thrown. The `begin()` and `end()` methods should provide just iterators to underlying attribute map. They should be valid even with empty header. This is a [documented way (e.g. page 12)](http://openexr.com/ReadingAndWritingImageFiles.pdf) how to open files by this library. IMHO there is nothing to check. – Michal Wirth May 12 '16 at 10:29
  • Moreover running `for (auto it = exr_header.begin(); it != exr_header.end(); ++it) { std::cout << it.name() << std::endl; }` in the Release mode correctly prints out all attribute names as expected. – Michal Wirth May 12 '16 at 10:38
  • Does it get any better if you change `const Imf::Header & exr_header = ...` to `const Imf::Header exr_header = ...`, changing the const reference to a normal stack. It should work as is as far as I can tell. – Dave S May 12 '16 at 11:54
  • @DaveS Good idea, thank you, but no. It still fails on the same assertion. – Michal Wirth May 12 '16 at 12:31
  • Create your own instance of `exe_header` instead of calling `exr_file.header()`. In other words, take a divide and conquer approach. You don't need that call to exr_file.header() to test this. `Imf::Header exr_header; exr_header.begin() != exr_header.end();` All that code does is create an `exe_header` on the stack, and then seeing if the `begin` and `end` iterators are not equal. Any well-coded class that has the iterator concept, this should be valid. If the code doesn't cause an assertion, then it is the particular instance being returned by `exe_file.header()` that may be faulty. – PaulMcKenzie May 12 '16 at 13:12
  • 3
    @MichalWirth Also, are these functions in an external DLL? If this is the case, the reason this is important is that if those functions exist in a DLL, what is being returned may well be incompatible with you're application's version of `Imf::Header`. In other words, you would need to build a debug version of the DLL's and use those for debugging. – PaulMcKenzie May 12 '16 at 15:23
  • @PaulMcKenzie Thank you! Yes, OpenEXR libraries are by default compiled as DLL and I've compiled them in the Release mode (because I just wanted to use them). This is apparently cause of all my problems. After recompiling OpenEXR in the Debug mode everything works as expected. I didn't know that mixing these modes should be strictly avoided on Windows. :-( I am coming from the GNU/Linux world and this is not a problem there. OK thanks again for pointing me into the right direction. :-) Should I write an answer to my question or do you want to do it (and therefore get the credit on SO)? – Michal Wirth May 15 '16 at 19:42
  • @MichalWirth The issue is that for Visual Studio, there is a big difference in the STL implementations between debug and release builds. Basically you were sending your debug build a different (and incompatible) iterator, namely a "release build" iterator. This is the problem with sending and passing STL or complex types across executable boundaries. Not only do the builds have to be the same, your builds have to be built with the same compiler, compiler version, etc. – PaulMcKenzie May 15 '16 at 20:33

0 Answers0