36

This is a simple question, but I can't seem to find a definitive answer.

If we have the following class:

class Test
{
...
  char testArray[10];

...
}; 

When we create an instance of Test, what is the default value of testArray[1]?

If it was a local array, it would be uninitialized.
If it was a static array, it would be initialized to 0.

What does it do when the array is a class member?

Luciano
  • 1,571
  • 3
  • 17
  • 23
  • It depends on the rest of the class definition including the definition of any constructors and potentially how the class instance is instantiated. Please show more code. – CB Bailey Oct 13 '11 at 20:55
  • What do you mean by "class member"? The example `testArray` you have shown, in C++, belongs to instances, not to the class. To have it belong to the class you would need to make it `static`, and define it elsewhere. – Karl Knechtel Oct 13 '11 at 21:03
  • 6
    @KarlKnechtel: Luciano is using the term exactly correctly. `testArray` is a non-static data member of the class. "Members of a class are data members, member functions (9.3), nested types, and enumerators. Data members and member functions are static or non-static; see 9.4." – Ben Voigt Oct 13 '11 at 21:06
  • Charles: Assume that the constructor of Test does not assign values to testArray. – Luciano Oct 13 '11 at 21:07
  • @CharlesBailey: Not really. If a constructor provides an initializer, then it wouldn't be *default-initialized*, but "What constitutes *default-initialization* for an array member?" is still a valid question. – Ben Voigt Oct 13 '11 at 21:07
  • @Luciano: "initialize" != "assign values to" – Ben Voigt Oct 13 '11 at 21:08
  • @BenVoigt: Not true. If the constructor provides an initializer it will be at least value-initialized. If the constructor doesn't provide an initializer it will be default initialized, if there is no user-declared constructor it depends on the initializer (if any) used to initialize the class and potentially on the storage duration of the object. – CB Bailey Oct 13 '11 at 21:10
  • @CharlesBailey: This question only asks about default-initialization, which excludes those cases. – Ben Voigt Oct 13 '11 at 21:12
  • @BenVoigt: No, the question asks what the "default value" of the member is which isn't the same thing. As a non-exact phrase, it invites clarification or a fuller answer describing all possibilities. – CB Bailey Oct 13 '11 at 21:15
  • @CharlesBailey: I'm looking at the title. – Ben Voigt Oct 13 '11 at 21:24
  • @Ben wow, the C++ community (/standards committee) terminology for these things is even stranger than I thought. – Karl Knechtel Oct 13 '11 at 22:59

3 Answers3

34

From the standard, section 8.5 [dcl.init]:

To default-initialize an object of type T means:

  • if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

  • if T is an array type, each element is default-initialized;

  • otherwise, no initialization is performed.

also section 12.6.2 [class.base.init]:

In a non-delegating constructor, if a given non-static data member or base class is not designated by a mem-initializer-id (including the case where there is no mem-initializer-list because the constructor has no ctor-initializer) and the entity is not a virtual base class of an abstract class (10.4), then

  • if the entity is a non-static data member that has a brace-or-equal-initializer, the entity is initialized as specified in 8.5;
  • otherwise, if the entity is a variant member (9.5), no initialization is performed;
  • otherwise, the entity is default-initialized (8.5).

So because the element type is char, when each element is default-initialized, no initialization is performed. The contents are left with arbitrary values.

Unless, of course, it's a member of an instance of the class, and the instance has static storage duration. Then the whole instance is zero-initialized, array members and all, before execution begins.

Ben Voigt
  • 277,958
  • 43
  • 419
  • 720
  • So if I understand correctly, the value will not be default initialized unless the instance of the Test class is a static instance? – Luciano Oct 13 '11 at 21:15
  • 2
    @Luciano: No, it will be default-initialized if the constructor doesn't specify an initializer for it (including the implicit constructor which enables initialization of aggregates). Default-initialization of a `char[]` is a no-op. If the instance has static storage duration, then there were zeros before, so after a no-op, it's still zero. In other cases, whatever was left in memory will determine the value. – Ben Voigt Oct 13 '11 at 21:23
  • @BenVoigt Can this rule apply to static array? if we define a local int, it will has a random value, but if we define a static int, it will be set to 0. Does static array has the same behavior? one discussion can be found here :https://stackoverflow.com/q/2091499/440403 – camino Jun 07 '18 at 14:10
  • 1
    @camino: A local with no initialization is not a "random" value, it is an indeterminate value. The difference is important and really screwed up cryptography software: https://research.swtch.com/openssl Elements of static arrays have static storage duration, and therefore get zero-filled. Being inside an array or other aggregate makes no difference. – Ben Voigt Jun 07 '18 at 14:25
  • @BenVoigtq I see, Thanks so much! – camino Jun 07 '18 at 14:28
7

It depends on may factors that you forgot to mention.

If your Test has no user-defined constructor or your user-defined constructor makes no efforts to initialize the array, and you declare the object of type Test as

Test test; // no initializer supplied

then it will behave in exactly the same way as you described above. For an automatic (local) object the contents of the array will remain unpredictable. For a static object the contents is guaranteed to be zero.

If your class has a user-defined constructor, then it will all depend on what constructor does. Again, keep in mind that static objects are always zero-initialized before any constructor has a chance to do anything.

If your class is an aggregate, then the content might depend on the aggregate initializer you supplied in the object declaration. For example

Test test = {};

will zero-initialize the array even for an automatic (local) object.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • 3
    And if `testArray()` is called within the constructor initialization list, each element in the array will be value-initialized (which means set to 0 for this particular case) – K-ballo Oct 13 '11 at 21:01
  • None of these cases are default initialization. The question asks what happens during default initialization. – Ben Voigt Oct 13 '11 at 21:09
  • 4
    @Ben Voigt: The question apparently misuses the term "default initialization". It happens rather often when people assume that if they do nothing at all then some sort of "default initialization" happens. In reality "default initialization" in C++ means something different. Which is why I don't restrict the answer to "default initialization". – AnT stands with Russia Oct 13 '11 at 21:34
0

I believe that if you don't initialize it when you declare it, it can be set to anything. Sometimes it is an address or random looking value.

Best practice is to initialize after declaring.

Wes
  • 4,781
  • 7
  • 44
  • 53