1

Per cppreference, the syntax for value initialization is:

  • [..]
  • T object {}; (since C++11)
  • [..]

It's already known that value-initialization is performed when an object is constructed with an empty initializer.

Per, [dcl.init]/8 (emphasis mine)

To value-initialize an object of type T means:

  • (8.1) if T is a (possibly cv-qualified) class type ([class]), then
    • (8.1.1) if T has either no default constructor ([class.default.ctor]) or a default constructor that is user-provided or deleted, then the object is default-initialized;
    • (8.1.2) otherwise, 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;
  • (8.2) [..]
  • (8.3) [..]

I interpret the term "no default constructor" as that there's no default constructor declared in the class. For example,

class S
{
    long double d;
    friend void f(const S&);
};

void f(const S& s) { std::cout << s.d; }

int main()
{
    S s{ };
    f(s); // 0
}

Since the class has "no default constructor", I'm expecting that the object s is default-initialized and the member s.d has indeterminate value. Why that's not the case?

I also have a confusion in understanding the point (8.1.1). How I can write this line of code T object {} without having a default constructor or with having a deleted default constructor? Notice the bold part, It's said that, "if T has either no default constructor or a default constructor that is deleted .."

Are there situations where objects of class types are value-initialized with deleted default constructor or without default constructor at all? Am I misreading 8.1.1?

3
  • 1
    In case of, "if T has no default constructor": That would be by declaring something like S::S(...). Commented Sep 7, 2022 at 19:25
  • 1
    "Why that's not the case?" because, per [class.default.ctor]/1, an explicitly-defaulted default constructor is implicitly-declared S() = default. Then the object gets zero-initialized per (8.1.2). Commented Sep 7, 2022 at 19:44
  • Check the rules for automatic generation of special member functions (your case falls into "user declares nothing") Commented Sep 7, 2022 at 20:09

1 Answer 1

2

Your class S does have a default constructor; it is just defined implicitly.

Per [class.default.ctor]/1:

A default constructor for a class X is a constructor of class X for which each parameter that is not a function parameter pack has a default argument (including the case of a constructor with no parameters). If there is no user-declared constructor for class X, a non-explicit constructor having no parameters is implicitly declared as defaulted ([dcl.fct.def]). An implicitly-declared default constructor is an inline public member of its class.

Therefore S{} will zero-initialize the object per [dcl.init]/8.1.2.

When [dcl.init]/8.1.1 refers to classes with no default constructor it means classes where the implicit default constructor doesn't get generated because user-defined constructors exist. That is, (8.1.1) would apply to the following classes:

struct NoDefaultCtor
{
    NoDefaultCtor(int) {}
};

struct UserProvidedDefaultCtor
{
    UserProvidedDefaultCtor() {}
};

struct DeletedDefaultCtor
{
    DeletedDefaultCtor() = delete;
};

For all three of those classes, value-initialization will perform default-initialization. In the case of NoDefaultCtor and DeletedDefaultCtor that default-initialization will fail, of course, but it's important that (8.1.1) catches those types so they don't fall through and get zero-initialized by (8.1.2).

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

7 Comments

"For all three of those classes, value-initialization will perform default-initialization." Why?
@John Because [dcl.init]/8.1.1 says so. If a class has no default constructor, a user-provided default constructor, or a deleted default constructor then value-initialization becomes default-initialization. Like you said, value-initialization/default-initialization will fail for NoDefaultCtor and DeletedDefaultCtor, but that doesn't mean it isn't performed (just that it fails when attempted).
When It's said "deleted", it doesn't said implicitly deleted or explicitly, so S(const S&) will apply (8.1.1) as the default one gets implicitly deleted. Right? In such case, the value-initialization will success and the default-initialization will apply also. Right?
@John No, the implicit default constructor is only deleted when the conditions in [class.default.ctor]/2 are met (basically if the class has members that can't be default-initialized). When a class has a user-declared constructor no implicit default constructor is ever generated at all.
"When a class has a user-declared constructor no implicit default constructor is ever generated at all." Thanks for this. So I was think that, the default constructor is generated then marked as deleted.
|

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.