Topic: Initialization of consts in aggregates
Author: assert@my-deja.com
Date: 2000/08/30 Raw View
I have come into this discussion late.
I feel that the following code is legal C and also legal C++.
typedef struct
{
const char st[4];
}S;
int main ()
{
S s = {"abc"};
}
That code compiles fine with Comeau 4.2.43 and g++ 2.95.2
Borland's C++ Builder and Microsoft's VC++ however will not.
VC++ thinks that S is not an aggregate, and
I can't think of anything that makes S a
non-aggregate.
[dcl.init.aggr] 8.5.1 Aggregates
An aggregate is an array or a class (clause 9) with no
user declared constructors (12.1), no private or pro tected
non static data members (clause 11), no base classes (clause 10),
and no virtual functions (10.3).
Nothing here suggests that S is not an aggregate but
perhaps somewhere in the text is another reference that
points out why it isn't (I doubt this, but it is possible).
Borland's C++ Builder Compiler version 5.4 will not allow
S to compile because there is no constructor (for s).
No mention of aggregates.
I happen to think that Comeau and g++ got it right.
8.5.1 covers all of this.
8.5.1 para 2
When an aggregate is initialized the initializer can
be an initializer clause consisting of a brace enclosed,
comma separated list of initializers for the members of
the aggregate, written in increasing subscript or member
order. If the aggregate contains subaggregates, this rule
applies recursively to the members of the subaggregate
In my example the member variable s will be properly
initialized via the aggregate list. The unnamed struct
(that I call S for convenience) is also an aggregate.
This is doable in both C and C++.
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Schwendt <schwendt@my-deja.com>
Date: 2000/08/18 Raw View
llewelly.@@edevnull.dot.com writes:
>As for 8.5/9, your example *does* have an initializer for the const
> object. Here is your example, repeated for reference:
>
> struct A
> {
> const char c[4];
> const int i;
> };
>
> class C
> {
> static const A a;
> };
>
> const A C::a = { 'T','E','S','T', 2 };
> this ^^^^^^^^^^^^^^^^^^is the initializer for A::c.
Of course it has an initializer. We all do know that static const-
qualified members can be initialized like that. It would be an error not
to initialize the constant C::a.
However, as the two previously mentioned compilers don't even compile that
far and complain about missing constructor(s) in struct A already, the
question is whether struct A is legal C++? And in case it isn't, where in
the C++ Standard is defined that a struct with constant members no longer
is an aggregate?
C programmers have told me it is legal C, at least with later C that has
been extended with "const". They couldn't tell me, though, whether it would
still make sense if non-constant members were moved in front as there
would be no way to omit these members during initialization. Sort of:
struct B
{
int x,y,z;
const char c[4]; // ooops! Must initialize x,y,z, too.
};
>When I originally saw your example, I thought it was legal; after all,
> the const objects were being intialized, and I could not see any
> reason why struct A was not an aggregate.
>
>Now I think think the standard is not at all clear on this matter.
>
>I looked for an issue relating to this, but I did not find one.
>
>[snip]
All I see are similarities between a struct with constant members and a
simple class with constant members.
class C
{
public:
const char c[4]; // error
const int i; // error, need constructor
};
Would be fine if we had no aggregates as a special case. Oh, well...
Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: alpair@my-deja.com
Date: 2000/08/09 Raw View
What makes you think that struct A should NOT have a compiler-generated
default constructor?
In article <m1ittc22j7.fsf@faldor.intranet>,
Michael Schwendt <schwendt@my-deja.com> wrote:
> Hi everyone!
>
> alpair@my-deja.com writes:
>
> >> struct A
> >> {
> >> const char a[4]; // error
> >> int b;
> >> };
> >>
> >> Error: Constant member A::a in class without constructors.
> >>
> >>
> >>
> >> class B
> >> {
> >> static const struct A a;
> >> const int b;
> >> public:
> >> B() : b(1) { ; }
> >> };
> >>
> >> const struct A B::a = { 'F','o','o', 1 };
> >> // or
> >> const struct A B::a = { {'F','o','o'}, 1 };
> >> // or
> >> const struct A B::a = { "Foo", 1 };
> >>
> >> All three cases of initialization cause a compiler error again.
> >
> >Have you checked the following paragraphs in Stroustrup's book "The
C++
> >PL, 3rd ed" ?
>
> Yes, I've checked every chapter that is relevant. I've also read the
> corresponding parts of the last C++ Standard Public Review Document.
>
> >10.4.2 Default Constructors
>
> Doesn't apply because only fundamental types are involved. Note that
I'm
> *not* trying to initialize a struct that has a constructor. I'm
trying to
> initialize an _aggregate_ containing at least one const member.
>
> >10.4.6.1 Necessary Member Initialization
>
> Doesn't say why the static member aggregate from the second example in
> this posting cannot be initialized via the brace-enclosed initializer
> list.
>
> >10.4.6.2 Member Constants
>
> Covers static integral constant members. But what about member
aggregates?
>
> >10.4.7 Arrays
>
> Applies to objects of class with default constructor. See 10.4.1,
where
> the constructor for class Table with default argument is defined.
>
> >You should find the answers there.
>
> Let me rephrase. Where in the C++ Standard is written that a simple
> structure with const-qualified members no longer is an aggregate?
>
> Which part exactly says that struct A at the top of this posting is
> illegal (if any)?
>
> The importance of this is, that if the example code is ill-formed,
there
> is a bug in egcs/g++ because that one compiles the code without
errors. If
> it is valid, however -- and a person I've spoken to on gcc-
bugs@gcc.gnu.org
> has no doubts that this is legal code -- both VC++ 5.0 and BC++ 5.5
have a bug.
>
> This is possible.
>
> struct A2
> {
> char c[4];
> int i;
> };
>
> A2 a2 = { "Foo", 1 };
>
> This is not?
>
> struct A3
> {
> const char c[4];
> int i;
> };
>
> A3 a3 = { "Foo", 1 };
>
> If so, there must be a part in the C++ Standard which defines it this
way.
> Which one is it? Section 8.5.1 of the Standard says that this is an
> aggregate, so brace-enclosed initialization is not ill-formed.
>
> Mike
>
> ---
> [ comp.std.c++ is moderated. To submit articles, try just posting
with ]
> [ your news-reader. If that fails, use mailto:std-
c++@ncar.ucar.edu ]
> [ --- Please see the FAQ before posting. ---
]
> [ FAQ: http://reality.sgi.com/austern_mti/std-
c++/faq.html ]
>
>
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Schwendt <schwendt@my-deja.com>
Date: 2000/08/09 Raw View
alpair@my-deja.com writes:
>What makes you think that struct A should NOT have a compiler-generated
>default constructor?
Well, I don't like to argue about proper C++ code because I have the
following options. I can conclude correct C++ from good books and
experience with buggy compilers. Or I can try to prove correct C++ with
the proper section(s) in the C++ Standard.
Struct A has members of built-in types only (which have a default
constructor). The compiler will try to generate a default constructor if
necessary and if the user has not declared a default constructor already.
Now, if you're aiming at the fact that const members must be initialized,
and this could only be done via either member-initializer list, or, in
case of static members, copy-initialization, I'd still like to see the
corresponding parts in the C++ Standard.
How is the Standard to be interpreted?
Is it the combination of sections 8.5/9, 9/4, 9.2/4, and 9.2/5, which also
classifies non-static const-qualified members (or arrays thereof) in
aggregates as ill-formed?
Regards,
Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: llewelly.@@edevnull.dot.com
Date: 2000/08/10 Raw View
Michael Schwendt <schwendt@my-deja.com> writes:
> alpair@my-deja.com writes:
>
> >What makes you think that struct A should NOT have a compiler-generated
> >default constructor?
>
> Well, I don't like to argue about proper C++ code because I have the
> following options. I can conclude correct C++ from good books and
> experience with buggy compilers. Or I can try to prove correct C++ with
> the proper section(s) in the C++ Standard.
>
> Struct A has members of built-in types only (which have a default
> constructor). The compiler will try to generate a default constructor if
> necessary and if the user has not declared a default constructor already.
> Now, if you're aiming at the fact that const members must be initialized,
> and this could only be done via either member-initializer list, or, in
> case of static members, copy-initialization, I'd still like to see the
> corresponding parts in the C++ Standard.
>
> How is the Standard to be interpreted?
>
> Is it the combination of sections 8.5/9, 9/4, 9.2/4, and 9.2/5, which also
> classifies non-static const-qualified members (or arrays thereof) in
> aggregates as ill-formed?
>
As for 8.5/9, your example *does* have an initializer for the const
object. Here is your example, repeated for reference:
struct A
{
const char c[4];
const int i;
};
class C
{
static const A a;
};
const A C::a = { 'T','E','S','T', 2 };
this ^^^^^^^^^^^^^^^^^^is the initializer for A::c.
As for 9/4, it says nothing one way or the other about const members.
9.2/4 is about constructs such as:
struct A
{
static const int f=1;
};
which your example does not contain.
9.2/5 just states that a member can be initialized by a constructor.
When I originally saw your example, I thought it was legal; after all,
the const objects were being intialized, and I could not see any
reason why struct A was not an aggregate.
Now I think think the standard is not at all clear on this matter.
I looked for an issue relating to this, but I did not find one.
[snip]
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Schwendt <schwendt@my-deja.com>
Date: 2000/08/07 Raw View
Hi everyone!
alpair@my-deja.com writes:
>> struct A
>> {
>> const char a[4]; // error
>> int b;
>> };
>>
>> Error: Constant member A::a in class without constructors.
>>
>>
>>
>> class B
>> {
>> static const struct A a;
>> const int b;
>> public:
>> B() : b(1) { ; }
>> };
>>
>> const struct A B::a = { 'F','o','o', 1 };
>> // or
>> const struct A B::a = { {'F','o','o'}, 1 };
>> // or
>> const struct A B::a = { "Foo", 1 };
>>
>> All three cases of initialization cause a compiler error again.
>
>Have you checked the following paragraphs in Stroustrup's book "The C++
>PL, 3rd ed" ?
Yes, I've checked every chapter that is relevant. I've also read the
corresponding parts of the last C++ Standard Public Review Document.
>10.4.2 Default Constructors
Doesn't apply because only fundamental types are involved. Note that I'm
*not* trying to initialize a struct that has a constructor. I'm trying to
initialize an _aggregate_ containing at least one const member.
>10.4.6.1 Necessary Member Initialization
Doesn't say why the static member aggregate from the second example in
this posting cannot be initialized via the brace-enclosed initializer
list.
>10.4.6.2 Member Constants
Covers static integral constant members. But what about member aggregates?
>10.4.7 Arrays
Applies to objects of class with default constructor. See 10.4.1, where
the constructor for class Table with default argument is defined.
>You should find the answers there.
Let me rephrase. Where in the C++ Standard is written that a simple
structure with const-qualified members no longer is an aggregate?
Which part exactly says that struct A at the top of this posting is
illegal (if any)?
The importance of this is, that if the example code is ill-formed, there
is a bug in egcs/g++ because that one compiles the code without errors. If
it is valid, however -- and a person I've spoken to on gcc-bugs@gcc.gnu.org
has no doubts that this is legal code -- both VC++ 5.0 and BC++ 5.5 have a bug.
This is possible.
struct A2
{
char c[4];
int i;
};
A2 a2 = { "Foo", 1 };
This is not?
struct A3
{
const char c[4];
int i;
};
A3 a3 = { "Foo", 1 };
If so, there must be a part in the C++ Standard which defines it this way.
Which one is it? Section 8.5.1 of the Standard says that this is an
aggregate, so brace-enclosed initialization is not ill-formed.
Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Schwendt <schwendt@my-deja.com>
Date: 2000/08/03 Raw View
Hi everyone!
We're having a portability problem here, caused by different free and/or
commercial C++ compilers that reject even _simple code_ like this:
struct A
{
const char a[4]; // error
int b;
};
Error: Constant member A::a in class without constructors.
The free egcs/g++ compiler has no problems with this. But how can it be
that popular compilers such as Borland C++ 5.5 or Visual C++ 5.0 disallow
brace-enclosed copy-initialization (_dcl.init.aggr_) of cv-qualified types
in aggregates?
What work-arounds -- other than dropping the "const" -- do other
programmers apply to get simple structs like above working? I really like
using constants wherever they make sense.
Or do I miss any part in the C++ Standard which states that a const member
would turn an aggregate into anything that _must_ have a constructor?
Well, I still couldn't initialize the member aggregate then, except if I
made it static. Then, however, the compilers don't permit brace-enclosed
aggregate initialization.
class B
{
static const struct A a;
const int b;
public:
B() : b(1) { ; }
};
const B::a = { 'F','o','o', 1 };
// or
const B::a = { {'F','o','o'}, 1 };
// or
const B::a = { "Foo", 1 };
All three cases of initialization cause a compiler error again.
Regards,
Mike
--
"I don't need luck. I got a system. I play all the odd red numbers."
- Danny Wilde (The Persuaders!)
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: Michael Schwendt <schwendt@my-deja.com>
Date: 2000/08/04 Raw View
Michael Schwendt <schwendt@my-deja.com> writes:
There's an obvious typo in the first posting. Thanks to those who notified
me. It doesn't affect the fundamental problem and my questions in the
first posting, though, because this mistake was just in the posting, not
in the original code:
>struct A
>{
> const char a[4]; // error
> int b;
>};
>
>Error: Constant member A::a in class without constructors.
>
>>>>>
>
>class B
>{
> static const struct A a;
> const int b;
>public:
> B() : b(1) { ; }
>};
>
>const B::a = { 'F','o','o', 1 };
>// or
>const B::a = { {'F','o','o'}, 1 };
>// or
>const B::a = { "Foo", 1 };
>
>All three cases of initialization cause a compiler error again.
instead of: const B::a =
read: const A B::a =
or: const struct A B::a =
Regards,
Mike
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]
Author: alpair@my-deja.com
Date: 2000/08/07 Raw View
In article <m11z056xu9.fsf@faldor.intranet>,
Michael Schwendt <schwendt@my-deja.com> wrote:
> Michael Schwendt <schwendt@my-deja.com> writes:
>
> There's an obvious typo in the first posting. Thanks to those who
notified
> me. It doesn't affect the fundamental problem and my questions in the
> first posting, though, because this mistake was just in the posting,
not
> in the original code:
>
> >struct A
> >{
> > const char a[4]; // error
> > int b;
> >};
> >
> >Error: Constant member A::a in class without constructors.
> >
> >>>>>
> >
> >class B
> >{
> > static const struct A a;
> > const int b;
> >public:
> > B() : b(1) { ; }
> >};
> >
> >const B::a = { 'F','o','o', 1 };
> >// or
> >const B::a = { {'F','o','o'}, 1 };
> >// or
> >const B::a = { "Foo", 1 };
> >
> >All three cases of initialization cause a compiler error again.
>
> instead of: const B::a =
> read: const A B::a =
> or: const struct A B::a =
>
> Regards,
> Mike
>
Hi Mike,
Have you checked the following paragraphs in Stroustrup's book "The C++
PL, 3rd ed" ?
10.4.2 Default Constructors
10.4.6.1 Necessary Member Initialization
10.4.6.2 Member Constants
10.4.7 Arrays
You should find the answers there.
- alpair
Sent via Deja.com http://www.deja.com/
Before you buy.
---
[ comp.std.c++ is moderated. To submit articles, try just posting with ]
[ your news-reader. If that fails, use mailto:std-c++@ncar.ucar.edu ]
[ --- Please see the FAQ before posting. --- ]
[ FAQ: http://reality.sgi.com/austern_mti/std-c++/faq.html ]