(This may be related to PR 30111 ) In this program, a default constructor fails to initialize the given array members to zero. Results are shown with several versions of gcc. === #include <string.h> #include <iostream> namespace { class Stats { friend void alpha(); private: int a_[12]; int b_[12]; }; void dirty_stack() { char array[4096]; memset(array, 0x11, 4096); } void alpha() { Stats my_stats = Stats(); for (int i = 0; i < 12; ++i) { std::cout << my_stats.a_[i] << " "; } std::cout << std::endl; } } int main() { dirty_stack(); alpha(); return 0; } === mec@hollerith:~/exp-array-default$ /home/mec/gcc-4.1.2/install/bin/g++ z3.cc && ./a.out 0 0 0 0 0 0 0 0 0 0 0 0 mec@hollerith:~/exp-array-default$ /home/mec/gcc-4.2.2/install/bin/g++ z3.cc && ./a.out 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 mec@hollerith:~/exp-array-default$ /home/mec/gcc-4.3-20071019/install/bin/g++ z3.cc && ./a.out 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153 286331153
The wording in the C++ standard working paper is as follows: 8.5 Initializers [dcl.init] -8- An object whose initializer is an empty set of parentheses, i.e., (), shall be value-initialized. Therefore, in <<< Stats my_stats = Stats(); >>>, the temporary object is value-initialized and then my_stats is copy-constructed. -5- To value-initialize an object of type T means: -- if T is a non-union class type without a user-provided constructor, then every non-static data member and base-class component of T is value-initialized;93) 93) Value-initialization for such a class object may be implemented by zero-initializing the object and then calling the default constructor. -- if T is an array type, then each element is value-initialized; -- otherwise, the object is zero-initialized Therefore, the temporary should be zero-initialized and the resulting copy should copy zeros. So, I conclude that gcc 4.2.1 is in error. (I suspect the compiler already eliminates the copy.) I suspect the problem arose in someone thinking that the zero initialization in front of a call to a default constructor was redundant. Alas, it is not. It is redundant only if the constructor initializes all fields, which is generally unknowable, though the compiler could determine so for many types and constructors.
I concur with Lawrence' analysis. I was bitten by this bug myself in my own code.
A regression hunt on powerpc-linux identified this patch: http://gcc.gnu.org/viewcvs?view=rev&rev=117834 r117834 | mmitchel | 2006-10-17 22:35:29 +0000 (Tue, 17 Oct 2006)
I still agree that we should fix this -- but it is worth noting that value-initialization did not exist in C++98. I believe that the current G++ behavior conforms to the original C++98 specification. Does anyone know if this change was in C++98 TC1? Or not until C++0x?
Subject: Re: [4.2/4.3 Regression] Default constructor fails to initialize array members Value initialization was in C++98 TC1 (2003) as a result of core issue 178.
There is some discussion about this bug in the following thread on gcc-patches: http://gcc.gnu.org/ml/gcc-patches/2008-01/msg00326.html
Jason, can you coordinate with Mark and help with the remaining P1 C++ regressions?
4.2.3 is being released now, changing milestones of open bugs to 4.2.4.
Subject: Bug 33916 Author: jason Date: Mon Feb 4 03:28:53 2008 New Revision: 132088 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132088 Log: PR c++/33916 * cp/init.c (build_value_init_1): New function. (build_value_init): New function. * cp/typeck2.c (build_functional_cast): Call it. * cp/cp-gimplify.c (cp_gimplify_init_expr): Handle its output. * cp/cp-tree.h (TYPE_HAS_USER_CONSTRUCTOR): Rename from TYPE_HAS_CONSTRUCTOR. * cp/class.c (finish_struct_bits, maybe_warn_about_overly_private_class, add_implicitly_declared_members): Adjust. (check_field_decls): Adjust. Remove warnings about reference/const in class without constructor. (check_bases_and_members): Adjust. Give those warnings here instead. * cp/decl.c (fixup_anonymous_aggr): Adjust. (check_initializer): Adjust, clarify logic slightly. (grok_special_member_properties): Adjust, only set if user-provided. * cp/rtti.c (create_tinfo_types): Don't set. * cp/cvt.c (ocp_convert): Remove exception for vtable_entry_type et al. Use same_type_ignoring_top_level_qualifiers_p. * cp/pt.c (check_explicit_specialization): Adjust. (instantiate_class_template): Adjust. * print-tree.c (print_node) [CONSTRUCTOR]: Print elements. Added: trunk/gcc/testsuite/g++.dg/init/value1.C trunk/gcc/testsuite/g++.dg/warn/Wextra-1.C trunk/gcc/testsuite/g++.dg/warn/Wextra-2.C Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/class.c trunk/gcc/cp/cp-gimplify.c trunk/gcc/cp/cp-tree.h trunk/gcc/cp/cvt.c trunk/gcc/cp/decl.c trunk/gcc/cp/init.c trunk/gcc/cp/pt.c trunk/gcc/cp/rtti.c trunk/gcc/cp/typeck2.c trunk/gcc/print-tree.c trunk/gcc/testsuite/g++.dg/init/ctor8.C
Fixed on the trunk.
Subject: Bug 33916 Author: jason Date: Tue Feb 12 06:37:34 2008 New Revision: 132254 URL: http://gcc.gnu.org/viewcvs?root=gcc&view=rev&rev=132254 Log: PR c++/34094 * decl2.c (cp_write_global_declarations): Don't write out static data members with DECL_IN_AGGR_P set. PR c++/33916 * Revert: 2006-10-17 Mark Mitchell <mark@codesourcery.com> PR c++/29039 * typeck2.c (build_functional_cast): Don't zero-initialize non-PODs; instead, call their constructors. Removed: branches/gcc-4_2-branch/gcc/testsuite/g++.dg/init/ctor8.C Modified: branches/gcc-4_2-branch/gcc/cp/ChangeLog branches/gcc-4_2-branch/gcc/cp/decl2.c branches/gcc-4_2-branch/gcc/cp/typeck2.c branches/gcc-4_2-branch/gcc/testsuite/ChangeLog
Fixed for 4.2.4 by reverting part of Mark's patch for PR 29039.
*** Bug 260998 has been marked as a duplicate of this bug. *** Seen from the domain http://volichat.com Page where seen: http://volichat.com/adult-chat-rooms Marked for reference. Resolved as fixed @bugzilla.