1

I'm using Microsoft Visual Studio Express 2013. I have a solution with 3 projects. 1 static library and two projects that reference the library. When the optimization for ONLY the library is set to /O2 I get some strange bugs in my game. When I disable the optimization, just for the library, it runs exactly as it does in debug. What would be causing this and how could I fix it?

rmaes4
  • 555
  • 9
  • 22
  • More details pls. What behaviour are you getting exactly? Can you isolate a part of the code that is causing the problem (please provide it) – axon Dec 12 '13 at 06:44
  • yes, more details please. any error message? – richard.g Dec 12 '13 at 06:57
  • All of my code is here https://github.com/kinglime/SFML2?files=1 what happens is, it doesn't throw any fatal errors. It actually runs but the problem is that it has a completely different result than in debug. – rmaes4 Dec 12 '13 at 06:58
  • 1
    Behavioral differences between builds is often due to uninitialized data. – Jonathan Potter Dec 12 '13 at 07:03
  • 1
    Mixing debug and release modules means you'll get different heaps and memory allocators. Memory allocated by one module and released by another will fail in all sorts of interesting ways. Try to be consistent with *all* debug or *all* release. – Roger Rowland Dec 12 '13 at 07:26
  • Note that the code generation optimization can be changed without changing whether debug or release runtimes are used. This can help determine if the problem is due to codegen optimizations or mixing runtimes. – Michael Burr Dec 12 '13 at 08:01
  • Sorry for the late response. I turned on /O2 for the project in debug mode. In order to do this I had to remove /ZI and /RTC1 for it to allow me to run it. All things considered it did actually work. This makes me very confused. Essentially I can only replicate the issue when /O2 is on in Release mode, not debug mode. All help would be appreciated. – rmaes4 Dec 12 '13 at 23:26

1 Answers1

2

You could have uninitialized variables which are automatically initialized by the compiler in debug mode, and not in release mode.

Additionally you could be facing alignment issue and minor memory overruns which you are protected from in debug mode due to having no optimizations but when optimizations are enabled and your code is aligned differently this could cause issues and undefined behavior.

Try making sure that all your variables are explicitly initialized, and not assume that:

int i;
is the same as int i = 0;
Max Shifrin
  • 809
  • 9
  • 24
  • MSVC does a pretty good job of detecting uninitialized local variable use in debug builds (the `/RTC1` option is on by default for Debug builds). However, the detection isn't 100%. And uninitialized heap memory and local variables in Debug builds are filled with deterministic values, but those values are designed to generally cause 'fast failures' (not hide problems) if used without being overwritten or after being freed. See http://stackoverflow.com/a/370362/12711 – Michael Burr Dec 12 '13 at 07:58
  • I think it is very dangerous practise to assume the compiler fills certain values to uninitialized variables. Static analysis tools will generally raise that as an issue, since such behaviour can change between compilers, version, operating systems etc... In the specific case if he assumes the variable is 0, and it is filled with something else, and he than has a test of var>0 it might work once and not work another time. MSVC actually fills dynamically allocated memory buffers with predetermined values, AFAIK it does not fill with good values uninitialized variables. – Max Shifrin Dec 12 '13 at 10:09
  • What MSVC does to uninitialized variables/memory in debug mode isn't intended to be something to depend on - the initialized values are designed to cause problems so the bugs get exposed. The `/RTC1` checks for using uninitialized locals goes beyond filling them with `0xCC`. `/RTC1` actually keeps a hidden flag for each local that is initialized to `false` and is set to `true` when the variable is initialized and checked each time the variable is used. If the flag is still false when the variable is used, it calls a function that will break into the debugger or cause a runtime failure message. – Michael Burr Dec 12 '13 at 15:47
  • I wanted to thank you all. I went through my application and fixed all my uninitialized variables. The program works flawlessly now in both debug and release. – rmaes4 Dec 13 '13 at 03:09