This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

BUG: aggregate initializer lists causing inconsistent behavior


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)


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]