views:

406

answers:

7

bool "bar" is by default true, but it should be false, it can not be initiliazied in the constructor. is there a way to init it as false without making it static?

Simplified version of the code:

foo.h

class Foo{
 public:
     void Foo();
private:
     bool bar;
}

foo.c

Foo::Foo()
{  
   if(bar)
   {
     doSomethink();
   }
}
+35  A: 

In fact, by default it's not initialized at all. The value you see is simply some trash values in the memory that have been used for allocation.

If you want to set a default value, you'll have to ask for it in the constructor :

class Foo{
 public:
     Foo() : bar() {} // default bool value == false 
     // OR to be clear:
     Foo() : bar( false ) {} 

     void foo();
private:
     bool bar;
}
Klaim
and therefore you have a almost 100% chance of `if (bar)` being true.
Adam Woś
some compilers will initialize the memory in debug builds to a specific pattern. If using one of those compilers, debug builds WILL have 100% chance of bar being true.
sean e
IIRC Darwin initialises memory to zero by default, so you can also end up with what appears to be inconsistent behaviour across platforms.
Adam Bowen
@Adam +1 - I didn't know that.
nbolton
@Adam: The language does not mandate any specific physical representation of `false` and `true`, which means that in theory an implementation can use, say, physical `1` for `true` and all other physical patterns for `false`. On such an implementation an unitialized `bool` object will amost always be `false`.
AndreyT
What are you (other commenters) talking about ? Both constructors from Klaim's code are correct. (I suspect you are unaware of the zero-initialization done in the first constructor -> see n3000 §8.5/5 /7 and /10)
Luc Hermitte
preconstruction FTW :D
Partial
@Luc: The comments aren't about Klaim's code but are about the repercussions of the first sentence in his answer (trying to show how the sentence results in the behavior that the questioner is seeing given the code in his question).
sean e
@AndreyT: +1 - you're dead on right. However, I was talking from my [Obj]C[++] experience, where it's just 0/1 the 'normal' way around :)
Adam Woś
@AndreyT: However, since an `int` 0 will convert too and from `bool` `false`, a non-zero `int` will convert to `bool` `true`, and `true` converts to 1, I'd expect the compiler to do the simple thing and make `false` binary 0. Few compilers push what they're allowed to do by the standard (I don't know of any that treat `a[++i] = i++;` to mean "format the hard drive").
David Thornley
Just to add compiler's experience: VC2003 initialize booleans to false in debug mode, gcc 3.4.2 let garbage... made for quite a bug for me over a year ago because of a library I used :/
Matthieu M.
@Matthieu - In think that depends on what you mean by "debug mode". My notes say that for a debug build VC will use /GZ to set memory to 0xcd or 0xcc (depending on it's a heap allocation or local) so an uninitialized bool would eval to `true`. I'd like to know if my notes are wrong (ideally without having to dig up a VC2003 install). My notes also say that VC versions 2005 or newer will use /RTC1 option by default in a Debug project to actively check at compile and runtime whether or not the variable is initialized, making it even more difficult to accidentally use an uninitialized variable.
Michael Burr
Doesn't the standard say anywhere that an uninitialized bool might be *neither* true nor false?
UncleBens
@UncleBens: yes, in a footnote the standard says, "Using a bool value in ways described by this International Standard as ‘undefined,’ such as by examining the value of an uninitializedautomatic variable, might cause it to behave as if it is neither true nor false". As always, undefined behavior means all bets are off...
Michael Burr
A: 

C / C++ don't initialize variables for you at all. The memory location which is now in use by bar had a value in it which is interpreted as "true". This will not always be the case. You must initialize it in your constructor.

Donnie
It depends. POD member variables aren't initialized, but non-POD members get default constructed. And, of course, global/static variables are initialized.
jamesdlin
A: 

This program has undefined behavior. Intrinsic types do not have constructors. You could do bool bar = bool(); but it's better to define the actual value in your foo class.

0A0D
A: 

Try this:

class Foo
{ 
  public: 
    void Foo(); 
  private: 
     bool bar; 
} 

Foo::Foo() : bar(false)
{
  if(bar) 
  { 
    doSomething(); 
  }
}
Bill
foo() is not Foo() ...
Klaim
Oops, @Klaim beat me to providing an example.
Bill
foo() is a typo, foo() should be Foo()
Christoferw
I updated the answer, hope this wasn't too rude of me.
nbolton
After OP updated question, foo() no longer exists, so I reverted, @Nick. Thanks though.
Bill
A: 

You can initialize any variable when you declare it.

bool bar = 0;
Dan
i thougt that same, but i get an C2864 error then:only static const integral data members can be initialized within a class
Christoferw
This is true for local variables, but not class members.
Bill
But not before C++0x…
Debilski
+4  A: 

Klaim's answer is spot on. To "solve" your problem you could use a constructor initialization list. I strongly suggest you read that page as it may clear up some similar queries you may have in future.

nbolton
A: 

Since you're using the value of bar in the ctor, I assume you're trying to set it before the object is created? I think you meant to make it a static class variable instead of an instance variable.

Paul Tomblin