1

Cppref states that value-initialization in C++ happens when

an object is constructed with an empty initializer.

Also, default-initialization happens when

an object is constructed with no initializer.

However, on the page for value-initialization, there is also the claim that

if T is a class type with a default constructor that is not user-declared (until C++11)neither user-provided nor deleted (since C++11) (that is, it may be a class with an implicitly-defined or defaulted default constructor), the object is zero-initialized and the semantic constraints for default-initialization are checked, and if T has a non-trivial default constructor, the object is default-initialized;

This tells me that there is a scenario, where an object

  • constructed with an initializer
  • that has an implicitly-defined or defaulted default constructor
  • and the above constructor is not trivial (possible, for example, by having the object contain non-static members with default initializers),

that object ends up being default-initialized rather than value-initialized.

The page on default-initialization states that the only 3 scenarios where it happens is either when there's no initializer present, or a member is missing from the constructor initializer list. Doesn't the above contradict those statements?

4
  • Yes, the definition of value-initialized for some cases defers to default-initialized Commented Sep 5, 2023 at 4:33
  • 1
    value-initialized only happens when there is no initializer (or an empty initializer, i.e. {} or ()) Commented Sep 5, 2023 at 4:36
  • Unless "no initializer" is the same as, or one form of an "empty initializer", your statement is not consistent with the header at the top of the cppref page for value-initialization. Commented Sep 5, 2023 at 13:52
  • Also, if value-initialized can defer to default-initialized, why isn't that listed as a fourth situation in which default-initialization is performed? Commented Sep 5, 2023 at 14:00

2 Answers 2

3

Think of "value-initialization" and "default-initialization" as processes rather than grammatical constructs. You can even think of them as "function calls" made by certain grammar.

The "function call" for "value-initialization" can itself call "default-initialization" in certain cases.

Sign up to request clarification or add additional context in comments.

2 Comments

I don't have a problem looking at them as processes. My concern is that the listed scenarios in which the process (if you will) of default-initialization happens, don't appear to include the scenario mentioned in the value-initialization page. Is it the case that that scenario actually matches one of those 3?
@user2565010 the context of "Default-initialization is performed in three situations:" is initialization scenarios, not including cases where the specification of a different type of initialization later defers to default-initialization for a part of it . Note that this is a website wording, not the language text of the Standard
1

If that implies that those are applied to exactly same object, no, it cannot.

Although a default-initialization of an object can result in same effect as a value-initialization with an empty initializer if that object is of a trivially-constructed type and its creation is result of a namespace-scope declaration.

Note: This one was misunderstood a while back and several old compilers were default-initializing an object with a non-standard layout in namespace scope or default-initializing such during value-initialization with empty initalizer in a function scope. Notable examples: MSVC 2008, MSVC 2010. That wasn't compliant behavior:

 // Note: Some non-compliant compiler is used
 struct A { int _a; };
 struct B : public A { int _b; };

 B foo() {
   return B(); // would not initialize _a. there was no compound 
               // initialization yet. Compiler automatically generated
               // a constructor for a class with an non-empty base.
 }
 // It was a nasty issue especially because in debug build 
 // default-initialization was equal to value-initialization to 0.
 // But not in release build.

Subobjects (parts of object) can be default-initialized while object is value-initialized, if

  • Object is of class type, which derived from class with user-defined constructor lacking appropriate element in initializer list.
  • Object is of class type with user-defined constructor lacking appropriate element in initializer list.
  • Object is an aggregate type (e.g. trivial class type or an array) and initializer-list lacks elements. In that case omitted members or array elements will be either default-initialized OR value-initialized, if they are trivial. So empty initializer of containing object can result in default initialization of its content.

1 Comment

You mention that default initialization can result in the same effect as value initialization. While true in effect, one or the other is supposed to happen from a C++ standard POV, and I wanted to check if cppref was wrong. Your answer seems to confirm what I understood from reading about this: there are not just 3 scenarios where default initialization happens.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.