views:

288

answers:

10

Based on below, am i right?

  • global_A reference is initialized to null.
  • global_int is 0
  • local_A reference is null
  • local_int is uninitialized
  • Both global_A.x and local_A.x is uninitialized.

THanks for any help.


A global_A;
int global_int;

class A {
  public : int x;
}

int main()
{
  int local_int;
  A local_A;
}
A: 

They all require to be initialized. The compiler will give you a warning about this.

Chad
Global variables are initialized to 0.
John Kugelman
Global variables are not initialized to zero.
Chad
@Chad: global variables reside in the BSS section, which is zeroed, thus making them initialised to 0 by default. Please, read http://en.wikipedia.org/wiki/Data_segment
jweyrich
@Chad: In C++ all objects with static storage duration (including so called "global variables") are *always zero initialized* before any other initialization begins.
AndreyT
@jweyrich: Not necessarily "zeroed" in that sense. A global variable of type `int S::*ptr` (pointer to data member of class S), will be initialized with `0xFFFF...` on many implementations (like GCC), which is how null-pointer is often represented in such types. BSS won't help you here.
AndreyT
if i read all the answers here .. there are some different from one person to another ..
extdummy
@extdummy No worries. The voting will sort out the correct answer(s). Just give it time for the votes to stabilize.
John Kugelman
@AndreyT: that's correct. Only non-POD are initialised to 0 AFAIK.
jweyrich
@jweyrich: No, *everything* with static storage duration is initially initialized to "logical zero", i.e. zero-initialized in the language sense of "zero", instead of just being filled with 0 bit pattern. Objects with constructors are later initialized again by their respective constructors.
AndreyT
@AndreyT: I see, thank you for the clarification.
jweyrich
@jweyrich Thanks for the answer and the link to the wiki page. I've been programming in C/C++ for 6 years and never, ever once thought that the global variables would be initialised to 0 by default. Personaly I think this is wrong because changing the storage location of a class or variable should not change how it is initialised by default eg.. If not inilaised it should be left un-initailised to prevent change in application behaviour.
Chad
+1  A: 

global_A and local_A are not references; they are objects and created using their default constructors. Default constructor has not been specified so it will be generated, which will do nothing so the member variable will remain uninitialized.

Hemal Pandya
So is any objects created for both global_A and local_A? Sori i am mixing Java with C++. When i say reference here .. i means address. So are those variables points to any objects there?
extdummy
C++, unlike Java, has both objects and pointers to objects. You're declaring objects, not pointers. The syntax for what you seem to *think* your code does is `A* global_A = NULL;`.
dan04
A: 

global_A reference is initialized to null.

No, its a valid object (constructed based on default constructor, which you don't have in your code but compiler adds that)

global_int is 0

yes

local_A reference is null

no, same reason as for global

local_int is uninitialized

no, its initialized to 0

Both global_A.x and local_A.x is uninitialized.

no both are initialized to 0

The local variables are not initialized.
John Kugelman
@John: `local_A` is initialized by a call to its default constructor.
Ben Voigt
A: 

This code won't compile unless you forward declare A.

global_A reference is initialized to null - No, it will reference an A object. global_int is 0 - Think so, need to check. local_A reference is null - No, same as with global_A. local_int is uninitialized - Yes, it will get some garbage value. Both global_A.x and local_A.x is uninitialized - Yes.

You can always debug and see for yourself.

Arjor
that was what i understood too but problem is when i print global_A or local_A reference .. nothing. It seems it is null value cos nothing printed
extdummy
How exactly do you print them?
Arjor
+4  A: 

There are no references in your code, so any of your points that mention "references" make no sense.

In your example, both global object - global_int and global_A - are zero-initialized. Both local objects - local_int and local_A - contain indeterminate values, which means that local_int and local_A.x are not initialized.

P.S. Of course, as other already noted, your code is non-compilable. You can't declare A objects before declaring class A (and you are missing a ; after the class definition).

AndreyT
A: 
A global_A;

This is an instace, not a pointer, your program will call the constructor before entering main.

To get a pointer to an instance and not an instance you have to write:

A* global_A;

global_int is initialized to 0, as all global variables are initialized to their defaults.

The variable A local_A will be initialized every time your program enters the function in which it is declared by a call to its constructor.

As before if you want a pointer to A you have to write A *local_A, but this time you have to initialize it to NULL yourself.

A *local_A = NULL;

The varialle local_int wont be initialized as it is a primitive type.

If local_A.x is initialized depends on the constructor of A, the default constructor will not initialize local_A.x. If x where a class instance creating an instance of A will initialize x with the constructor of its class.

josefx
At least in gcc, global_int will be initialized to 0 because it is global.
jbernadas
@jbernadas you are right, its part of the language specification. Fixed it
josefx
+4  A: 

Basically, whenever you declare a variable, the compiler will call its default constructor unless you specify otherwise.

The language level types (e.g. pointers, 'int', 'float', 'bool', etc) "default constructor" does absolutely nothing, it just leaves the memory as it is when it is declared (global/static variables are special cases, refer to chubsdad's answer for more on the specifics). This means that they can be pretty much anything because you usually can't be sure what was in that memory previously or even where the memory came from (except in the case of the 'placement new' operator).

The class you created has no constructors so the compiler will generate a default constructor for you which simply calls the constructor of each of its members/variables. If you incorporate the information provided in the previous paragraph, you can see that the variable 'x' will have its default constructor called, which does nothing, and thus is isn't initialized to any value.

As others have said, there are no references in your code or pointers, so the term 'NULL' is invalid in all cases here. NULL usually refers to a pointer which, like other language level types, doesn't get set to anything until you assign it a value (unless of course its a global/static variable).

Grant Peters
Excellent explanation. Lucid and to the point.
Henrik Erlandsson
The statement that the default constructor of primitive types does nothing is misleading, since calling it explicitly will in fact set the value to the respective 'null' value (`int a = int();` initializes `a` to zero). I guess it is more intuitive to say that the default constructors are not called automatically for primitive types, leaving those uninitialized.
Ferdinand Beyer
Sometimes, the "default constructor" is called for primitives automatically as well. One such example: `struct { int x; float f; } s = { 9 }; assert(s.x == 9); assert(s.f == 0.0f);`
Dennis Zickefoose
Really, the issue is calling it a default constructor at all.
Dennis Zickefoose
@Dennis @Ferdinand: Good points, though I do prefer thinking of it this way as it provides a consistent model for variable initialization. There are probably a few edge cases that I've missed but IMHO, this is probably the best way of explaining it to a "newbie" as following it shouldn't lead to any problems (i.e. its better to assume its not initialized when it is, instead of assuming it is initialized when its not) and its not too far from the truth anyway.
Grant Peters
+1  A: 

Just for the sake of completeness if you had references:

References must be initialized on declaration, otherwise you get punished by a compiler error. This means a reference always needs another value or reference it refers to (like the says), this is ensured by the compiler so you cannot forget it. This also implies that references can never be null pointers. However the object they refer to might become invalid.

jdehaan
+5  A: 

Building up on Andrey's response.

$3.6.2- "Objects with static storage duration (3.7.1) shall be zero-initialized (8.5) before any other initialization takes place.". In OP, "global_A" and "global_int" have static storage duration. "local_int" and "local_A" have no linkage as these are local objects.

$8.5/5- To zero-initialize an object of type T means:

— if T is a scalar type (3.9), the object is set to the value of 0 (zero) converted to T;

— if T is a non-union class type, each nonstatic data member and each base-class subobject is zeroinitialized;

— if T is a union type, the object’s first named data member89) is zero-initialized;

— if T is an array type, each element is zero-initialized;

— if T is a reference type, no initialization is performed.

$6.7.4/4- "The zero-initialization (8.5) of all local objects with static storage duration (3.7.1) is performed before any other initialization takes place. A local object of POD type (3.9) with static storage duration initialized with constant-expressions is initialized before its block is first entered. An implementation is permitted to perform early initialization of other local objects with static storage duration under the same conditions that an implementation is permitted to statically initialize an object with static storage duration in namespace scope(3.6.2). Otherwise such an object is initialized the first time control passes through its declaration; such an object is considered initialized upon the completion of its initialization. If the initialization exits by throwing an exception, the initialization is not complete, so it will be tried again the next time control enters the declaration. If control re-enters the declaration (recursively) while the object is being initialized, the behavior is undefined."

EDIT 2:

$8.5/9- "If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a nonstatic object, the object and its subobjects, if any, have an indeterminate initial value90); if the object or any of its subobjects are of const-qualified type, the program is ill-formed."

In general, you want to read up these sections along with $8.5 for good hold on this aspect.

Chubsdad
A: 

well guys .. i am more confused as i see responses from here. Anyway i did a test as shown below:

1 #include

  2 using namespace std;
  3 
  4 class A {
  5 
  6 public :
  7         A() : x(9) {};
  8         int x;
  9 
 10 };
 11 
 12 A global_a;
 13 int global_b;
 14 
 15 int main() {
 16 
 17         A local_a;
 18         int local_b;
 19         cout << "global_a.x = " << global_a.x << '\n';
 20         cout << "local_a.x = " << local_a.x << '\n';
 21 
 22         cout << "global_b = " << global_b << '\n';
 23         cout << "local_b = " << local_b << '\n';
 24 
 25 }

Results using my g++ compiler on ubuntu linux:

global_a.x = 9

local_a.x = 9

global_b = 0

local_b = 0

I do think local_b should be undefined but somehow compiler initialized it by default. However local_a .. i am not sure if that should be initialized by default. From the testing here .. local_a seem to be initialized. Not sure if that complies with standard c++ specification (eg C++ PRimer 4th edition says default constructor is used regardless where a class variable is declared - does that means variable of class type is initialized whether it is global or local?).

Whatever it is .. it is one big hell of confusion. Maybe i should quit learning C++. Java is so much more straight forward. Hell yeahhh!!

extdummy
Adding a default constructor changes how instances of `A` are initialized. Now both `global_a` and `local_a` are initialized by the default constructor. As for `local_b`, it just *happens* to be 0. It is indeed uninitialized, though. This isn't something you can test by writing a program since an uninitialized variable can very easily "happen" to be 0 if that's what was in its memory location.
John Kugelman
The confusing thing with `A` is that if you don't supply a constructor then the compiler provides a default constructor. Except this default constructor does nothing! It is a no-op. It leaves the `x` field with whatever its default value is: for `global_a` that means `x` has its default value of 0, whereas for `local_a` it means that `x` is uninitialized since its default state is to be uninitialized.
John Kugelman