1

In developing a 32 bit Windows command line program we recently encountered a situation where the debug version works as expected while the release version shows odd behavior in its computations that it should not. Now, this was not an uncommon problem 20+ years ago. For the release version, compiler optimization gets turned on and compiler optimization even now is not certain to work for all cases. So, in the past if we encountered this problem we would turn off the compiler optimizations - perhaps selectively if speed or space considerations were really important. This time we turned off all optimizations and the problem remained! The only difference between debug and release versions amounts to a series of compiler and loader settings. We went back and altered the release setting to match the debug settings as best we could and the problem remains! That We have never seen before.

This has all been on the VC6 platform, which we generally have been using for 32 bit Windows. That is right Microsoft Visual C++ 6.0. Our preference for VC6 is that we were beta tester for Microsoft on all versions of their C/C++ package up through VC6 and had been very active in the debugging of the optimizers. But since we've had no real problems with VC8 we tried that. In this case we just had VC8 convert the project we had been using. To our amazement I found that VC8 shows exactly the same problem. The debug version works and the release version does not. We may try creating the thing from scratch in VC8 and see if that makes a difference, but we rather suspect that it will not. At this point we do not understand this at all. It has to be a compiler switch setting somewhere that we are missing. Or does it?

What else can cause a difference between a release and a debug build?

KevinDTimm
  • 14,226
  • 3
  • 42
  • 60
C.O.
  • 2,281
  • 6
  • 28
  • 51
  • 2
    If a debug and release build behaves differently it could be a sign of you using uninitialized memory or variables somewhere. – Some programmer dude Apr 20 '17 at 14:31
  • 2
    I saw VC allocating some extra stack space in debug and not in release. So possibly you go out of some bound on a stack-allocated array that now shows up in release. You can check this by inspecting the assembler. – Paul Ogilvie Apr 20 '17 at 14:40
  • @Paul Ogilvie Thanks for the observation, will look at that. – C.O. Apr 20 '17 at 14:41
  • 1
    This class of defect is a strong reason to do your testing in release mode, while doing you debugging in debug mode. – EvilTeach Apr 20 '17 at 14:42
  • 2
    I also recommend using some sort of static analyzer, as those are generally better at finding problems like these than the compilers. – Some programmer dude Apr 20 '17 at 14:43
  • 3
    I also recommend turning all warnings on. Consider building your solution under msvc 2015 with all warnings turned on. It's amazing what 2015 can detect that 6 can't. – EvilTeach Apr 20 '17 at 14:47
  • "release version shows odd behavior in its computations that it should not" - some elaboration here can help to get better answers – Andriy Tylychko Apr 20 '17 at 14:53
  • 1
    @C.O. You could also build the release version with debug information. Just go into your project settings for "Release" and turn on debugging on the compiler and linker (you will see they have been turned off -- just turn them back on). Then you can use the debugger just as you always did in debug builds. You may also want to turn off optimizations in the Release mode initially -- if the error comes up again, then debug the app using the debugger. – PaulMcKenzie Apr 20 '17 at 15:53
  • @PaulMcKenzie Thank you, good idea. – C.O. Apr 20 '17 at 16:17
  • Check if you do not have ESSENTIAL code inside an `ASSERT`. Yes, I did the mistake: http://stackoverflow.com/a/21111839/383779 – sergiol Apr 21 '17 at 14:00

2 Answers2

1

Debug implementation may have different result than Release due to sanity check they may do (specially in case of undefined behaviours).

A nice example: using std::min or std::max with a NaN (see Why does Release/Debug have a different result for std::min?) will give different result in Release/Debug (see my own answer where I analyzed the function implementation).

Community
  • 1
  • 1
jpo38
  • 20,821
  • 10
  • 70
  • 151
1

In general you will find that a debug executable is different from a release executable in in a couple of ways. This is obvious just by looking at the file sizes of the executables. Possible causes include

  • Debug may have additional code compiled in to do error checking
  • Debug generally has optimization disabled, while Release is likely to have a high level.
  • Debug may default initialize automatic variables to zero, while Release does not initialize at all.
  • Debug may carry additional information to associate the executable code with the source code, while Release does not.

My best advice is to initialize all of your variables, even if it seems stupid. Verify that all your memory allocations work, and that you free properly in scope.

The static analyzer comment above is excellent advice. You can get similar benefits by compiling with a newer compiler.

Take a look at CPPCHECK, or one of the many commercial checkers.

I recommend you upgrade to the latest compiler in any case.

Best of Luck.

Evil.

EvilTeach
  • 28,120
  • 21
  • 85
  • 141
  • On your third bullet, add "_automatic_" as all global variables must be initialized "to their vaue or to zero" as per the standard. VC Debug initializes the automatic variables to a marker value. – Paul Ogilvie Apr 20 '17 at 16:26
  • On your fourth bullet, yes, it may contain additional information, but not additional code. Then this _information_ cannot influence the _behavior_. – Paul Ogilvie Apr 20 '17 at 16:28
  • @paul. Actually it can. the additional information may cause data to be loaded at different places in memory. – EvilTeach Apr 20 '17 at 18:36