This is the mail archive of the
gcc-bugs@gcc.gnu.org
mailing list for the GCC project.
BUG: aggregate initializer lists causing inconsistent behavior
- To: egcs-bugs at cygnus dot com
- Subject: BUG: aggregate initializer lists causing inconsistent behavior
- From: "Thanatos" <fvali at biotrack dot com>
- Date: Thu, 17 Sep 1998 18:12:29 -0500
- Organization: Biometric Applications & Techonology
Regarding: Egcs 1.1 c++/g++
struct T
{
int i;
void f() { cout << "T::i = " << i << endl; }
T() { } //Lets make this class a non-aggregate
};
struct S
{
//This class is still an aggregate, right? even though it contains
//a member that is a non-aggregate. Atleast that's what can be
//inferred from the draft.
T t;
void f() { cout << "t.i = " << t.i << endl; }
};
int main()
{
T t = T();
t.f();
S s = { T() };
s.f();
S s2 = { };
s2.f();
}
Now in the initialization of T t = T(), t is copy-initialized, and t.i
should be an indeterminate value, because it is never explicitly
initialized (8.5/9), which is what is displayed by f(), so this is
standard behavior. But in S s = { T() }, and S s2 = { } which are
semantically equivalent s.t.i & s2.t.i are initialized to 0?? The draft
states that :
[ 12.6.1 Explicit initialization [class.expl.init]
2 When an aggregate (whether class or array) contains members of class
type and is initialized by a brace-enclosed initializer-list
(_dcl.init.aggr_), each such member is copy-initialized (see
_dcl.init_) by the corresponding assignment-expression. If there are
fewer initializers in the initializer-list than members of the aggre-
gate, each member not explicitly initialized shall be copy-initialized
(_dcl.init_) with an initializer of the form T() (_expr.type.conv_),
where T represents the type of the uninitialized member. [Note:
_dcl.init.aggr_ describes how assignment-expressions in an initial-
izer-list are paired with the aggregate members they initialize.
]
thus S::t should be intialized with T() and S::t.i should have an
indeterminate value and not neccesarily be zero-initialized.
Thus it seems that the semantics of copy-intialization with T() is
different depending on whether a brace-enclosed initializer list
(resulting in implicit zero-intialization of scalar members) is used to
specify the copy-init, or a prenthesized initializer list is used
(resulting in indeterminate values for scalar members).
You can replace the T() with a T(int) constructor and once again similar
differences in the semantics are perceived.
If you don't define any contructors, then T t = T(); causes zero-init of
members, yet
T t;, doesn't.
This must be a bug right, or does an indeterminate value encapsulate a
zero-initialized value?
thanks a lot,
-fais
P.S As always, any feedback, however brief, will be greatly appreciated
;-)
--
Biometric Applications & Technology
Faisal Vali - Software Engineer (B.A.T man)
----------------------------------------------------
To be a philosopher is not merely to have subtle thoughts, nor even to
found
a school, but so to love wisdom as to live according to its dictates a
life of
simplicity, independence, magnanimity, and trust. It is to solve some of
the
problems of life, not only theoretically, but practically. (Henry David
Thoreau)