Date: Tue, 11 Jul 2023 12:45:00 +0300
The standard says [dcl.init]:
http://eel.is/c++draft/dcl.init#general-9.1.1
"To value-initialize an object of type T means:
(9.1) if T is a (possibly cv-qualified) class type ([class]), then
(9.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;
...
(9.3)
otherwise, the object is zero-initialized."
(note the emph on *user-provided*, as opposed to user-declared).
This causes very surprising behavior like the following (
https://godbolt.org/z/rxYcsYdTd):
#include <iostream>
using namespace std;
int main() {
struct Thingy1 { // No user provided default ctor
int i;
};
cout << Thingy1().i << endl; // Zero
Thingy1 t1;
cout << t1.i << endl; // Junk
struct Thingy2 {
Thingy2() {}; // User provided default ctor
int i;
};
cout << Thingy2().i << endl; // Junk
struct Thingy3 {
Thingy3() = default; // user DECLARED, not provided
int i;
};
// This is the surprising bit:
cout << Thingy3().i << endl; // Zero again!
}
----------------------------
I've chased down the origin of this to defect report 1368 from 2011 (
https://cplusplus.github.io/CWG/issues/1368.html). Quote:
" struct A {
int i;
A() = default;
A(int i): i(i) { }
};
value-initialization leaves A::i uninitialized. This seems like an
oversight."
I don't understand the "This seems like an oversight" bit. I spoke with
quite a few people who were equally surprised and annoyed by this behavior
- it seems the common expectation is that `Thingy3() = default` would
express an intention identical to `Thingy3() {}`.
Now before I try to write a paper to promote (what I perceive to be) a fix
- am I missing something? Is there reason to make A::i zero-initialized
despite the intention expressed in `A() = default` ?
Thank you,
-Ofek Shilon
http://eel.is/c++draft/dcl.init#general-9.1.1
"To value-initialize an object of type T means:
(9.1) if T is a (possibly cv-qualified) class type ([class]), then
(9.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;
...
(9.3)
otherwise, the object is zero-initialized."
(note the emph on *user-provided*, as opposed to user-declared).
This causes very surprising behavior like the following (
https://godbolt.org/z/rxYcsYdTd):
#include <iostream>
using namespace std;
int main() {
struct Thingy1 { // No user provided default ctor
int i;
};
cout << Thingy1().i << endl; // Zero
Thingy1 t1;
cout << t1.i << endl; // Junk
struct Thingy2 {
Thingy2() {}; // User provided default ctor
int i;
};
cout << Thingy2().i << endl; // Junk
struct Thingy3 {
Thingy3() = default; // user DECLARED, not provided
int i;
};
// This is the surprising bit:
cout << Thingy3().i << endl; // Zero again!
}
----------------------------
I've chased down the origin of this to defect report 1368 from 2011 (
https://cplusplus.github.io/CWG/issues/1368.html). Quote:
" struct A {
int i;
A() = default;
A(int i): i(i) { }
};
value-initialization leaves A::i uninitialized. This seems like an
oversight."
I don't understand the "This seems like an oversight" bit. I spoke with
quite a few people who were equally surprised and annoyed by this behavior
- it seems the common expectation is that `Thingy3() = default` would
express an intention identical to `Thingy3() {}`.
Now before I try to write a paper to promote (what I perceive to be) a fix
- am I missing something? Is there reason to make A::i zero-initialized
despite the intention expressed in `A() = default` ?
Thank you,
-Ofek Shilon
Received on 2023-07-11 09:45:13