[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 Andrew Pinski changed: What|Removed |Added CC||iamsupermouse at mail dot ru --- Comment #15 from Andrew Pinski --- *** Bug 111771 has been marked as a duplicate of this bug. ***
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #14 from m.cencora at gmail dot com --- Yeah, in CWG issue comments it is much more clear - but I cannot find such a wording in C++ latest draft. English is not my native language so this one is on me.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #13 from Jonathan Wakely --- And that's clearly the committee's intent: https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#302 "Zero the object, then call the default generated constructor" ... "Zero first, and generate the object code for the default constructor when it's needed for value-initialization cases" https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#543 "Change 9.4 [dcl.init] to specify that non-union class objects with no user-declared constructor are value-initialized by first zero-initializing the object and then calling the (implicitly-defined) default constructor,"
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #12 from Jonathan Wakely --- I don't see any ambiguity: "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;" It doesn't say zero-init OR default-init, it very clearly says zero-init AND default-init.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #11 from m.cencora at gmail dot com --- Nvm, I understood this rule differently. You are saying that initialization is two step: - first zero-initialized, - then default-initialized. For me the way this rule is written is ambiguous.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 m.cencora at gmail dot com changed: What|Removed |Added CC||m.cencora at gmail dot com --- Comment #10 from m.cencora at gmail dot com --- Does it really apply? Base constructor is user-provided hence non-trivial, hence Derived defaulted default constructor is non-trivial as well. Which means we end up in this clause: "and if T has a non-trivial default constructor, the object is default-initialized"
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 Jonathan Wakely changed: What|Removed |Added Status|UNCONFIRMED |NEW Ever confirmed|0 |1 Last reconfirmed||2023-04-21 --- Comment #9 from Jonathan Wakely --- Confirmed. using size_t = decltype(sizeof(0)); extern "C" void* memset(void*, int, size_t); extern "C" int printf(const char*, ...); void* operator new(size_t, void* p) { return p; } struct Base { Base() {} // user-provided constructor int x; }; struct Derived : public Base { Derived() = default; // default constructor satisfying (2) of // https://en.cppreference.com/w/cpp/language/value_initialization private: int y; }; int main () { char b_mem[sizeof(Derived)]; memset(b_mem, 0x55, sizeof(Derived)); printf("b_mem[0]: %d\n", int(b_mem[0])); Derived* b = new(b_mem) Derived{}; printf("b->x (should be 0): %d\n", b->x); b->~Derived(); } With any optimization level except -O0 this prints: b_mem[0]: 85 b->x (should be 0): 1431655765
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #8 from Andrew Pinski --- (In reply to Pablo Anigstein from comment #7) > Here is an updated example: https://godbolt.org/z/YePjhxKE4. I don't see an updated example, all I see is an URL ...
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #7 from Pablo Anigstein --- (In reply to Jonathan Wakely from comment #5) > (In reply to Jonathan Wakely from comment #3) > > (In reply to Pablo Anigstein from comment #2) > > > (In reply to Andrew Pinski from comment #1) > > > > Hmm, > > > > I noticed that since GCC 7 with -std=c++17, the b.x is not initialized > > > > at > > > > all. So the question I have is there a difference between C++ standards > > > > here? > > > > Derived is an aggregate in C++17, so b{} does aggregate init, not value > > init. > > And that means its Base subobject is copy-initialized from {} which means we > get a value-initialized object, so it's correct that b.x is not initialized > in C++17 (which is what is shown in your godbolt link, because you didn't > specify any -std option to override the -std=gnu++17 default). > > With -std=c++14 it looks like b.x is always set to zero, if I'm reading the > assembly output correctly (but I'm probably not). Here is an updated example: https://godbolt.org/z/YePjhxKE4. Note that now Derived is not an aggregate for any standard version due to the private member. Still zero-initialization does not happen for the Base sub-object for the case where Base has a user-provided default constructor when compiling with -O1 and above.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #6 from Pablo Anigstein --- (In reply to Jonathan Wakely from comment #3) > (In reply to Pablo Anigstein from comment #2) > > (In reply to Andrew Pinski from comment #1) > > > Hmm, > > > I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at > > > all. So the question I have is there a difference between C++ standards > > > here? > > Derived is an aggregate in C++17, so b{} does aggregate init, not value init. > > > > Note the issue is we call Base's constructor after doing the zero > > > initialization and the Base's constructor has a clobber in it which I > > > think > > > is correct. > > Maybe we should only clobber in the complete object constructor _ZN4BaseC1Ev > and not in _ZN4BaseC2Ev. > > > > This is all front-end generation and not exactly related to the > > > optimizations directly. > > > > There is no difference between C++ standards in this respect. > > Before C++11 there was no zero-init at all. Since C++11 the spec keeps > changing, but the effects of zero-init are substantially the same. But > Derived is an aggregate since C++17. Thank you for the correction. I still think there is non-conformance for all standards including C++17, I will post a modified example in a comment below. > > Aside: What does the comment "not a default constructor" mean in the > testcase? I guess he meant "user-provided".
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #5 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #3) > (In reply to Pablo Anigstein from comment #2) > > (In reply to Andrew Pinski from comment #1) > > > Hmm, > > > I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at > > > all. So the question I have is there a difference between C++ standards > > > here? > > Derived is an aggregate in C++17, so b{} does aggregate init, not value init. And that means its Base subobject is copy-initialized from {} which means we get a value-initialized object, so it's correct that b.x is not initialized in C++17 (which is what is shown in your godbolt link, because you didn't specify any -std option to override the -std=gnu++17 default). With -std=c++14 it looks like b.x is always set to zero, if I'm reading the assembly output correctly (but I'm probably not).
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #4 from Jonathan Wakely --- (In reply to Jonathan Wakely from comment #3) > Derived is an aggregate since C++17. Correction, it's an aggregate *only* in C++17. In C++20 the rule changed again so the user-declared (but not user-provided) constructor makes it a non-aggregate.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 --- Comment #3 from Jonathan Wakely --- (In reply to Pablo Anigstein from comment #2) > (In reply to Andrew Pinski from comment #1) > > Hmm, > > I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at > > all. So the question I have is there a difference between C++ standards > > here? Derived is an aggregate in C++17, so b{} does aggregate init, not value init. > > Note the issue is we call Base's constructor after doing the zero > > initialization and the Base's constructor has a clobber in it which I think > > is correct. Maybe we should only clobber in the complete object constructor _ZN4BaseC1Ev and not in _ZN4BaseC2Ev. > > This is all front-end generation and not exactly related to the > > optimizations directly. > > There is no difference between C++ standards in this respect. Before C++11 there was no zero-init at all. Since C++11 the spec keeps changing, but the effects of zero-init are substantially the same. But Derived is an aggregate since C++17. Aside: What does the comment "not a default constructor" mean in the testcase?
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 panigstein at hotmail dot com changed: What|Removed |Added CC||panigstein at hotmail dot com --- Comment #2 from panigstein at hotmail dot com --- (In reply to Andrew Pinski from comment #1) > Hmm, > I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at > all. So the question I have is there a difference between C++ standards here? > > Note the issue is we call Base's constructor after doing the zero > initialization and the Base's constructor has a clobber in it which I think > is correct. > > This is all front-end generation and not exactly related to the > optimizations directly. There is no difference between C++ standards in this respect. For a class that has a defaulted default constructor (Derived), value-initialization consists of zero-initialization followed by default-initialization. The clobbering of the Base sub-object is incorrect here and makes the implementation of value-initialization non-conforming.
[Bug c++/108993] Value initialization does not occur for derived class , for gcc versions > 5
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=108993 Andrew Pinski changed: What|Removed |Added Keywords||wrong-code --- Comment #1 from Andrew Pinski --- Hmm, I noticed that since GCC 7 with -std=c++17, the b.x is not initialized at all. So the question I have is there a difference between C++ standards here? Note the issue is we call Base's constructor after doing the zero initialization and the Base's constructor has a clobber in it which I think is correct. This is all front-end generation and not exactly related to the optimizations directly.