6

To use an uninitialized object of built-in type with automatic storage duration is undefined behaviour. Of course I recommend strongly always to initialize member variables of built-in type inside a class type. Despite that, I assume that a member of built-in type without an initializer is always initialized to zero, if the corresponding object of class type has static storage duration (i.e. global object). My assumption is, that the complete memory of an object of class type with static storage duration is zeroed out.

Example:

#include <iostream>
using namespace std;

class Foo {
public:
        int bar;
};

Foo a;

int main() {
        Foo b;
        cout << "a.bar " << a.bar << "\n";
        cout << "b.bar " << b.bar << "\n";
        return 0;
}

Compile:

$ g++ -o init init.cpp -Wall -pedantic # gcc 7.2.1
init.cpp: In function ‘int main()’:
init.cpp:14:31: warning: ‘b.Foo::bar’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  cout << "b.bar " << b.bar << "\n";
                               ^~~~

GCC complains only about the member, of class type object with automatic-storage duration b.bar not a.bar. So I am right?

Please feel free to modify the title of this question.

Thank you

Peter
  • 2,240
  • 3
  • 23
  • 37
  • 2
    Zero initialization. And nmdv, btw. – StoryTeller - Unslander Monica Dec 21 '17 at 17:49
  • 1
    " My assumption is, that the complete memory of an object of class type is inside the BSS" - C++ (and C) have nothing to say about a `BSS`. –  Dec 21 '17 at 17:51
  • @StoryTeller: Thanks found this with "zero initalization" http://en.cppreference.com/w/cpp/language/zero_initialization which states "If T is an non-union class type, all base classes and non-static data members are zero-initialized, and all padding is initialized to zero bits. The constructors, if any, are ignored." But what means "nmdv"? – Peter Dec 21 '17 at 17:57
  • 1
    Not My Downvote. Got scared when a -1 appeared right as I posted my comment. Though it seems to have been reversed since. – StoryTeller - Unslander Monica Dec 21 '17 at 17:58
  • @StoryTeller: Thanks :) – Peter Dec 21 '17 at 18:02
  • 1
    @R Sahu: The linked question especially doesn't handle the mentioned situation. – Peter Dec 21 '17 at 18:03
  • You could make this even more interested by giving Foo a virtual function.. At the moment it is a POD-struct (even though you used the `class` keyword). The answer would still be the same though - it would be zero initialized. – Martin Bonner supports Monica Dec 21 '17 at 18:16
  • @R Sahu: I agree with the OP. None of the answers in the linked question cover a member of a statically allocated class object (because the OP of *that* question was under the impression that *all* members were properly initialized). – Martin Bonner supports Monica Dec 21 '17 at 18:18
  • Possible duplicate of [Is global memory initialized in C++?](https://stackoverflow.com/questions/60653/is-global-memory-initialized-in-c) – 1201ProgramAlarm Dec 21 '17 at 18:34

2 Answers2

3

As said in the comment, it is zero initialized, [basic.start.init]/3:

Variables with static storage duration ([basic.stc.static]) or thread storage duration ([basic.stc.thread]) shall be zero-initialized ([dcl.init]) before any other initialization takes place.[...]

And zero initializing an object, zero initializes all its non-static data members and padding bits, [dlc.init]/6.2:

To zero-initialize an object or reference of type T means:[...]

  • if T is a (possibly cv-qualified) non-union class type, each non-static data member and each base-class subobject is zero-initialized and padding is initialized to zero bits;[...]

So, as you said the complete object memory is zeroed out (bits belonging to its value representation and its padding-bits).

Community
  • 1
  • 1
Oliv
  • 17,610
  • 1
  • 29
  • 72
  • 1
    The result of *zero-initializing* an object, is not necessarily the same as setting all its bits to zero. (I have used a platform where the natural representation for a null pointer had the first 16 bits set to 0x0FFF - and that would be the result of zero initializing a pointer.) – Martin Bonner supports Monica Dec 22 '17 at 07:41
3

Not to initalize an object of built-in type with automatic storage duration is undefined behaviour.

No, that's not correct. See [dcl.init]/12:

If no initializer is specified for an object, the object is default-initialized. When storage for an object with automatic or dynamic storage duration is obtained, the object has an indeterminate value, and if no initialization is performed for the object, that object retains an indeterminate value until that value is replaced ([expr.ass]). [ Note: Objects with static or thread storage duration are zero-initialized, see [basic.start.static]. — end note] If an indeterminate value is produced by an evaluation, the behavior is undefined except in the following cases:

Foo b; is defined behavior, cout << "b.bar " << b.bar << "\n"; (before b.bar has a set value) is undefined behavior.

GCC complains only about the member, of class type object with automatic-storage duration b.bar not a.bar.

GCC's family of warnings related to uninitialized variables are provided for convenience and often contains false positives. It is not possible in the general case to have accurate warnings for every scenario (it's as hard as solving the halting problem). It's simply letting you know that you're trying to use a value that you did not explicitly initialize, i.e has indeterminate value, which is probably not what you wanted.