Jump to content

  • Log In with Google      Sign In   
  • Create Account

VC++ F5 and Ctrl+F5, I'm mad...


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
21 replies to this topic

#1 EXEed   Members   -  Reputation: 108

Like
0Likes
Like

Posted 28 August 2012 - 09:42 PM

Hi folks,

I'm stuck on a problem.. I wrote a OpenGL rendering framework using VC 2012. It loads model and shader files from hard drive. It works very well when I launch it by F5, BUT if I use Ctrl+F5, nothing is ever drawn on the screen.. Also under both 'modes', all files have been read in properly. I cannot figure out why, please help me if you have any ideas. Thanks in advance.

The libraries I used: glew 1.9, SDL 1.2, glm 0.9.3.4, C++11

Sponsor:

#2 Hodgman   Moderators   -  Reputation: 31800

Like
3Likes
Like

Posted 28 August 2012 - 11:11 PM

Most likely you're relying on an uninitialized variable somewhere. Try turning the compiler's warning setting up to it's maximum level.
Do you use multi-threading or custom memory allocation?

#3 EXEed   Members   -  Reputation: 108

Like
0Likes
Like

Posted 29 August 2012 - 06:35 AM

Thanks for your answer Hodgman, regarding

Most likely you're relying on an uninitialized variable somewhere. Try turning the compiler's warning setting up to it's maximum level.

I maximized the warning levels but there are no variables uninitialized.

Do you use multi-threading or custom memory allocation?

Neither of them have been used so far. Though I found the rendering results may differ from time to time. E.g. very few times when I start the app only one of two meshes is drawn while other times nothing is drawn.

Edited by liZHao, 29 August 2012 - 06:42 AM.


#4 Hodgman   Moderators   -  Reputation: 31800

Like
0Likes
Like

Posted 29 August 2012 - 07:23 AM

I maximized the warning levels but there are no variables uninitialized.

This just means there's no obvious uninitialized variables, there still might be some :/

e.g. This code creates a new uninitialized variable, but the compiler won't issue a warning about it:
MyStruct* data = (MyStruct*)malloc( sizeof(MyStruct) );


#5 SiCrane   Moderators   -  Reputation: 9668

Like
1Likes
Like

Posted 29 August 2012 - 08:05 AM

Note that even without weird creation mechanisms, if you pass the address of an uninitialized variable around, MSVC won't give you a warning. Ex:
void foo1(int a) {}
void foo2(int * a) {}

int main(int, char **) {
  int a;
  int b;
  foo1(a);  // C4700
  foo2(&b); // no warning
}


#6 Martins Mozeiko   Crossbones+   -  Reputation: 1422

Like
0Likes
Like

Posted 29 August 2012 - 08:26 AM

SiCrane - but that's normal usage of output argument. Why would you want warning for that? Then a lot of C style programs will give tons of warnings.

#7 BitMaster   Crossbones+   -  Reputation: 4431

Like
0Likes
Like

Posted 29 August 2012 - 08:33 AM

SiCrane did not say that should produce a warning. He said that is a situation where an uninitialized variable is used in a potentially dangerous context. That is an important point because the OP seems to assume no "uninitialized variable" warnings mean his program does not use them.

Edited by BitMaster, 29 August 2012 - 08:33 AM.


#8 kunos   Crossbones+   -  Reputation: 2207

Like
0Likes
Like

Posted 29 August 2012 - 08:48 AM

Try to use CppCheck on it, it's usually pretty good at founding uninitialised variables in C++, it has already saved my neck more than a couple of times since I've started using it.
Stefano Casillo
Lead Programmer
TWITTER: @KunosStefano
AssettoCorsa - netKar PRO - Kunos Simulazioni

#9 brx   Members   -  Reputation: 720

Like
0Likes
Like

Posted 29 August 2012 - 09:52 AM

The thing I don't get about the unitialized variable assumption ist that both F5 and Ctrl+F5 launch the debug build (one with debugger attached, the other without) so the variables that stay uninitialized in release but initialized in debug should be initialized as well. Or am I missing something?

Try to attach the debugger after launching with Ctrl+F5 maybe that helps in seeing what happens?

#10 EXEed   Members   -  Reputation: 108

Like
0Likes
Like

Posted 29 August 2012 - 10:19 AM

I have found the reason: there is a boolean member variable indicating the visibility of a mesh and it has not been initialized explicitly.. thus in debug mode (F5) it is initialized with 'true' otherwise it is random..
What confuses me is why VC initializes a boolean variable with 'true'?

#11 SiCrane   Moderators   -  Reputation: 9668

Like
1Likes
Like

Posted 29 August 2012 - 10:20 AM

The thing I don't get about the unitialized variable assumption ist that both F5 and Ctrl+F5 launch the debug build (one with debugger attached, the other without) so the variables that stay uninitialized in release but initialized in debug should be initialized as well. Or am I missing something?

One of life's many little annoyances is that the MSVC CRT behaves differently depending on whether or not a debugger is attached during initialization. Take this code for example:
int main() {
  std::vector<char *> vec;
  for (int i = 0; i < 1000; i++) {
    vec.push_back(new char);
  }
  std::sort(vec.begin(), vec.end());
  ptrdiff_t min_diff = vec[1] - vec[0];
  for (int i = 1; i < 999; i++) {
    ptrdiff_t diff = vec[i + 1] - vec[i];
    if (diff < min_diff) min_diff = diff;
  }
  std::cout << min_diff << std::endl;
}
With MSVC 2010 targeting x86, Debug with F5 spits out 64, Debug with Ctrl-F5 gives 48, Release/F5: 32, Release/Ctrl-F5: 16.

As long as your code relies only on defined behavior, then these differences don't really have much of an impact other than allocations using more or less memory than you might otherwise expect. However, once you dip into undefined or implementation defined behavior, like the contents of uninitialized memory, then these differences can give you all kinds of headaches.

Edited by SiCrane, 29 August 2012 - 10:21 AM.


#12 SiCrane   Moderators   -  Reputation: 9668

Like
1Likes
Like

Posted 29 August 2012 - 10:23 AM

I have found the reason: there is a boolean member variable indicating the visibility of a mesh and it has not been initialized explicitly.. thus in debug mode (F5) it is initialized with 'true' otherwise it is random..
What confuses me is why VC initializes a boolean variable with 'true'?

MSVC's debug heap fills uninitialized memory with certain bit patterns to make debugging common errors easier to find. Note that they are all non-zero, which means translates into true in most cases they are treated as a boolean value.

#13 brx   Members   -  Reputation: 720

Like
0Likes
Like

Posted 29 August 2012 - 10:27 AM

Thanks SiCrane, I didn't know that. I always thought it only depends on the build configuration.

#14 kunos   Crossbones+   -  Reputation: 2207

Like
0Likes
Like

Posted 29 August 2012 - 10:32 AM

this is one of the things that really drives me mad about C++ ... there should be (is there?) a compiler switch to auto initialise every variable to zero and get rid of this '60 cold war age nonsense, I'd happily pay the performance penalty for that.
Stefano Casillo
Lead Programmer
TWITTER: @KunosStefano
AssettoCorsa - netKar PRO - Kunos Simulazioni

#15 Adam_42   Crossbones+   -  Reputation: 2617

Like
0Likes
Like

Posted 29 August 2012 - 03:19 PM

Another really simple way to get uninitialized variables with no compiler warnings is when they are class / struct member variables - the compiler won't complain if the constructor doesn't initialize all member variables.


It's not too hard to override global operator new so that it sets the memory to zero before returning it, just don't forget to do it for all the different variations (array version, nothrow version, etc). Of course there's an obvious performance cost to doing that, and it only works for heap allocations - doing that for stack allocated objects would need some help from the compiler, and Visual Studio can usually catch those in debug anyway.

#16 Mussi   Crossbones+   -  Reputation: 2097

Like
3Likes
Like

Posted 29 August 2012 - 03:29 PM

I can't remember the last time I ran into a problem like this. Rather than finding ways to ensure that variables are initialized to something random(should a boolean initialize to true or false?), I'd recommend you to train yourself in recognizing and avoiding code with undefined behaviour.

#17 Cornstalks   Crossbones+   -  Reputation: 6991

Like
4Likes
Like

Posted 29 August 2012 - 03:59 PM

this is one of the things that really drives me mad about C++ ... there should be (is there?) a compiler switch to auto initialise every variable to zero and get rid of this '60 cold war age nonsense, I'd happily pay the performance penalty for that.

That compiler switch is called "Use a different language." :) Even if there were such a switch though, I would beg everyone to not use it, because then you write poor code that is heavily tied to your compiler and compiler switches. Plus: what if library A authors relied on some specific default initialization values, but library B authors relied on some different default initialization values? What do you do if you want to use both library A and library B?

C++11 introduced the ability to initialize class members at declaration time, so that may help in some cases with missing/forgetting things. In the end, you just gotta get used to it if you're going to use C++ and train your eyes to pay attention to when a variable is declared, when it's assigned, and when it's used. The C++ mantra is "pay only for what you use" (C has this mantra even more so), and sometimes the desired value-assignment can't be done until a later point in time (so C & C++ ask: why waste instructions and CPU time writing a useless value?).
[ I was ninja'd 71 times before I stopped counting a long time ago ] [ f.k.a. MikeTacular ] [ My Blog ] [ SWFer: Gaplessly looped MP3s in your Flash games ]

#18 krippy2k8   Members   -  Reputation: 646

Like
2Likes
Like

Posted 29 August 2012 - 04:15 PM

this is one of the things that really drives me mad about C++ ... there should be (is there?) a compiler switch to auto initialise every variable to zero and get rid of this '60 cold war age nonsense, I'd happily pay the performance penalty for that.


And make your code completely unsafe for anybody else that uses it.

Automatically initializing variables to zero is not just a trivial performance issue, it can have huge performance implications on some code and algorithms, and the potential benefits of doing so are marginal; it can eliminate some bugs, while making other bugs harder to track down.

#19 SiCrane   Moderators   -  Reputation: 9668

Like
0Likes
Like

Posted 29 August 2012 - 06:09 PM

Thanks SiCrane, I didn't know that. I always thought it only depends on the build configuration.

The MSVC CRT heap behavior actually depends on a number of variables. One of them is operating system, this being because most of the time the CRT delegates allocations to the Windows API HeapAlloc() function, so if the OS behavior changes, the CRT behavior will change. However, older versions of MSVC takes a bit further. MSVC 2005 and earlier would only use HeapAlloc() if the OS was Win2000 or later. On earlier OS versions, they would use an internal heap management system... unless an environment variable was set to override the heap selection mechanism. MSVC 2008 defaulted to always using the OS heap, unless overridden by the environment variable. As far as I can tell MSVC 2010 got rid of the alternate heaps entirely, and instead adds a check to see if the OS is Win XP or 2003 Server, in which case it explicitly enables the low fragmentation heap. And to mix things up a bit, the OS heap itself depends on at least one environment variable. If _NO_DEBUG_HEAP is set to 1, then some of the behavior changes for when a debugger is present aren't used.

I also don't make any promises about this being a comprehensive list.

#20 Simian Man   Members   -  Reputation: 1010

Like
1Likes
Like

Posted 30 August 2012 - 10:11 AM

I normally use valgrind to check for things like this. It walks through your program and gives dynamic warnings on uninitialized variables and also memory leaks




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS