Topic: aggregate initializer question


Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Fri, 25 Jun 2004 21:10:35 +0000 (UTC)
Raw View
In article <2c8c44c3.0406242243.42e7e27b@posting.google.com>, krazyman
<dusk47@hotmail.com> writes
>maeder@glue.ch (Thomas Maeder) wrote in message news:<m2659idv9k.fsf@madbox2.local>...
>> dusk47@hotmail.com (krazyman) writes:
>>
>> > Why is the second test below illegal according to the C++ std?
>>
>> Because the C++ Standard includes a version of the C Standard, and the
>> latter says that.
>
>C also restricts you to declaring a variable at the top of a function,
>whereas C++ does not, so it's not like the rules of C are immutable.


Yep, the rules of C are not immutable which is exemplified by the fact
that late declarations are now fine in C as well, though not yet, IIRC,
in conditional expressions.

--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: francis@robinton.demon.co.uk (Francis Glassborow)
Date: Sat, 26 Jun 2004 07:06:08 +0000 (UTC)
Raw View
In article <2c8c44c3.0406242243.42e7e27b@posting.google.com>, krazyman
<dusk47@hotmail.com> writes
>> This is also not correct, and you should get a diagnostic message from
>> a conforming compiler. The return type of main() has to be int.
>
>MSVC allows this syntax as a convenience for times when you dont care
>about the return value.

A fact of which we are all too well aware. But just because someone
allows you to jump off a bridge is not a reason for doing so. You are in
comp.std.c++ so please write Standard conforming C++.

>
>>
>>
>> >  // legal
>> >  Test t1={1,2};
>>
>> This is an initialization.
>>
>>
>> >
>> >  // illegal
>> >  Test t2;
>> >  t2={1,2};
>>
>> This is an attempt to do an assignment.
>
>Sure, technically they are different, but practically (as far as I
>understand) they could be implemented in the compiler exactly the same
>way, so I don't understand why the standard limited the "aggregate"
>syntax to initialization than rather allowing it as a convenience for
>all assignment statements, and I was hoping someone could clear that
>up for me.

It isn't immutable and I am considering adding it in my proposal for a
uniform initialisation syntax by extending it into assignment but it
really isn't of great import and I am much more interested in dealing
with array initialisation than with tinkering with little 'wouldn't it
be nice' issues.


--
Francis Glassborow      ACCU
Author of 'You Can Do It!' see http://www.spellen.org/youcandoit
For project ideas and contributions: http://www.spellen.org/youcandoit/projects

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dusk47@hotmail.com (krazyman)
Date: Wed, 23 Jun 2004 06:47:43 +0000 (UTC)
Raw View
Why is the second test below illegal according to the C++ std?  Both
tests seem equivalently easy to implement for the compiler.

--------------
typedef struct {
   int x,y;
} Test;

void main() {
 // legal
 Test t1={1,2};

 // illegal
 Test t2;
 t2={1,2};
}

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: kuyper@wizard.net (James Kuyper)
Date: Wed, 23 Jun 2004 19:48:15 +0000 (UTC)
Raw View
dusk47@hotmail.com (krazyman) wrote in message news:<2c8c44c3.0406221755.50887272@posting.google.com>...
> Why is the second test below illegal according to the C++ std?  Both
> tests seem equivalently easy to implement for the compiler.
>
> --------------
> typedef struct {
>    int x,y;
> } Test;
>
> void main() {
>  // legal
>  Test t1={1,2};
>
>  // illegal
>  Test t2;
>  t2={1,2};
> }

It could be done, it wasn't. I can't comment with certainty about how
hard it would be to implement, but it does have features that could
lead to human confusion, which usually corresponds to compiler
difficulty.

C99 added a feature called compound literals which would allow
creation of unnamed objects of a specified type, which would allow
something very close to what you're asking for:

t2 = (Test){1,2};

This feature might be under consideration for inclusion in C++.
However, it's less attractive in C++ than in C, because user-defined
constructors allow an alternative approach that is syntactically quite
similar.

struct Test { // Need a named struct type to define a constructor.
  int x,y;
  Test(int new_x, int new_y): x(new_x), y(new_y) {};
};


Test t2;
t2 = Test(1,2);

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: maeder@glue.ch (Thomas Maeder)
Date: Thu, 24 Jun 2004 15:47:48 +0000 (UTC)
Raw View
dusk47@hotmail.com (krazyman) writes:

> Why is the second test below illegal according to the C++ std?

Because the C++ Standard includes a version of the C Standard, and the
latter says that.


> Both tests seem equivalently easy to implement for the compiler.

The two operations are fundamentally different. One allows aggregate
initialization, the other doesn't.


> --------------
> typedef struct {
>    int x,y;
> } Test;
>
> void main() {

This is also not correct, and you should get a diagnostic message from
a conforming compiler. The return type of main() has to be int.


>  // legal
>  Test t1={1,2};

This is an initialization.


>
>  // illegal
>  Test t2;
>  t2={1,2};

This is an attempt to do an assignment.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: brok@rubikon.pl ("Bronek Kozicki")
Date: Thu, 24 Jun 2004 15:49:10 +0000 (UTC)
Raw View
James Kuyper wrote:
> This feature might be under consideration for inclusion in C++.
> However, it's less attractive in C++ than in C, because user-defined
> constructors allow an alternative approach that is syntactically quite
> similar.
>
> struct Test { // Need a named struct type to define a constructor.
>   int x,y;
>   Test(int new_x, int new_y): x(new_x), y(new_y) {};
> };

... but due to user-defined constructor Test is no longer POD (see
clause 8.5.1). There are some things in C++ that are allowed only with
PODs, and that's where bracket-initialization is especially useful in
C++. I think that similar "bracket-assignment" as proposed by OP would
me also useful for PODs. I would also like to see similar initialization
of PODs in constructor initializer list - useful when POD is subobject
of full blown class and indispensable when such subobject is const. I do
not say that both features are really missing in C++, as these might be
emulated with separate initialization and assignment (unless POD
subobject is const). But that might allow us to write some programs
simpler, easier to read and opimize (by compiler).


B.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dusk47@hotmail.com (krazyman)
Date: Thu, 24 Jun 2004 21:48:06 +0000 (UTC)
Raw View
kuyper@wizard.net (James Kuyper) wrote in message news:<8b42afac.0406230725.2cc1823a@posting.google.com>...
> dusk47@hotmail.com (krazyman) wrote in message news:<2c8c44c3.0406221755.50887272@posting.google.com>...
> > Why is the second test below illegal according to the C++ std?  Both
> > tests seem equivalently easy to implement for the compiler.
> >
> > --------------
> > typedef struct {
> >    int x,y;
> > } Test;
> >
> > void main() {
> >  // legal
> >  Test t1={1,2};
> >
> >  // illegal
> >  Test t2;
> >  t2={1,2};
> > }
>
> It could be done, it wasn't. I can't comment with certainty about how
> hard it would be to implement, but it does have features that could
> lead to human confusion, which usually corresponds to compiler
> difficulty.
>
> C99 added a feature called compound literals which would allow
> creation of unnamed objects of a specified type, which would allow
> something very close to what you're asking for:
>
> t2 = (Test){1,2};
>
> This feature might be under consideration for inclusion in C++.
> However, it's less attractive in C++ than in C, because user-defined
> constructors allow an alternative approach that is syntactically quite
> similar.
>
> struct Test { // Need a named struct type to define a constructor.
>   int x,y;
>   Test(int new_x, int new_y): x(new_x), y(new_y) {};
> };
>
>
> Test t2;
> t2 = Test(1,2);

That is nice but quite often I'm using structures defined in 3rd party
headers written long ago by people who only knew C, so the modifying
the struct definition is undesirable.  Rather than forcing me to
rewrite the struct definition to add a C++ constructor, it would be
convenient if C++ simply supported the aggregate initializer syntax
everywhere.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: musiphil@bawi.org (Seungbeom Kim)
Date: Fri, 25 Jun 2004 05:28:04 +0000 (UTC)
Raw View
===================================== MODERATOR'S COMMENT:
 This thread risks running offtopic for this group -- followups
might consider redirecting discussion to comp.lang.c++.moderated.


===================================== END OF MODERATOR'S COMMENT
Bronek Kozicki wrote:

> James Kuyper wrote:
>
>>This feature might be under consideration for inclusion in C++.
>>However, it's less attractive in C++ than in C, because user-defined
>>constructors allow an alternative approach that is syntactically quite
>>similar.
>>
>>struct Test { // Need a named struct type to define a constructor.
>>  int x,y;
>>  Test(int new_x, int new_y): x(new_x), y(new_y) {};
>>};
>
>
> ... but due to user-defined constructor Test is no longer POD (see
> clause 8.5.1). There are some things in C++ that are allowed only with
> PODs, and that's where bracket-initialization is especially useful in
> C++. I think that similar "bracket-assignment" as proposed by OP would
> me also useful for PODs. I would also like to see similar initialization
> of PODs in constructor initializer list - useful when POD is subobject
> of full blown class and indispensable when such subobject is const. I do
> not say that both features are really missing in C++, as these might be
> emulated with separate initialization and assignment (unless POD
> subobject is const). But that might allow us to write some programs
> simpler, easier to read and opimize (by compiler).

Right. I have been in trouble several times trying to decide
whether my class should be a POD without user-defined constructors,
or it should have one being a non-POD. Adding one gives the convenience
of writing class literals, but takes away the POD-ness at the same time.

     struct point
     {
         int x, y;
         point(int xx, int yy) : x(xx), y(yy) { }  // whether to have
                                                   // this one or not?
     };

Could there be a general guideline for this kind of problems?

What are the things that are allowed only for PODs? I have stumbled over
these things, but I don't remember quite well now..

--
Seungbeom Kim

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Fri, 25 Jun 2004 05:29:55 +0000 (UTC)
Raw View
On Wed, 23 Jun 2004, James Kuyper wrote:

| dusk47@hotmail.com (krazyman) wrote in message news:<2c8c44c3.0406221755.50887272@posting.google.com>...
| > Why is the second test below illegal according to the C++ std?  Both

An embarassment.

| > tests seem equivalently easy to implement for the compiler.
| >
| > --------------
| > typedef struct {
| >    int x,y;
| > } Test;
| >
| > void main() {
| >  // legal
| >  Test t1={1,2};
| >
| >  // illegal
| >  Test t2;
| >  t2={1,2};
| > }
|
| It could be done, it wasn't. I can't comment with certainty about how
| hard it would be to implement, but it does have features that could
| lead to human confusion, which usually corresponds to compiler
| difficulty.

It isn't harder than handling the initialization case.  In fact,
there is a proposal for C++0x to add sequence constructors to C++.
If that proposal is accepted, it would render the original question
a non issue.

| C99 added a feature called compound literals which would allow
| creation of unnamed objects of a specified type, which would allow
| something very close to what you're asking for:
|
| t2 = (Test){1,2};
|
| This feature might be under consideration for inclusion in C++.
| However, it's less attractive in C++ than in C, because user-defined
| constructors allow an alternative approach that is syntactically quite
| similar.

Please, have a look at the literal/sequence constructor proposal.

| struct Test { // Need a named struct type to define a constructor.
|   int x,y;
|   Test(int new_x, int new_y): x(new_x), y(new_y) {};
| };

It is unnecessary verbose.  Furthermore, it changes Test from a POD
to non-POD -- and that can make a difference.
Of course, you could work around with various simulates; still, they
are unnecessary complexity and unattractive.

--
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
  Texas A&M University -- Computer Science Department
 301, Bright Building -- College Station, TX 77843-3112

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: gdr@cs.tamu.edu (Gabriel Dos Reis)
Date: Fri, 25 Jun 2004 05:30:04 +0000 (UTC)
Raw View
On Thu, 24 Jun 2004, Thomas Maeder wrote:

| > Both tests seem equivalently easy to implement for the compiler.
|
| The two operations are fundamentally different. One allows aggregate
| initialization, the other doesn't.

Still, not harder to implement.

[...]

| >  // illegal
| >  Test t2;
| >  t2={1,2};
|
| This is an attempt to do an assignment.

Yes, but there is no conceptual fundamental reason why it should not
be allowed.

--
                                                        Gabriel Dos Reis
                                                         gdr@cs.tamu.edu
  Texas A&M University -- Computer Science Department
 301, Bright Building -- College Station, TX 77843-3112

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: dusk47@hotmail.com (krazyman)
Date: Fri, 25 Jun 2004 19:38:07 +0000 (UTC)
Raw View
maeder@glue.ch (Thomas Maeder) wrote in message news:<m2659idv9k.fsf@madbox2.local>...
> dusk47@hotmail.com (krazyman) writes:
>
> > Why is the second test below illegal according to the C++ std?
>
> Because the C++ Standard includes a version of the C Standard, and the
> latter says that.

C also restricts you to declaring a variable at the top of a function,
whereas C++ does not, so it's not like the rules of C are immutable.

>
>
> > Both tests seem equivalently easy to implement for the compiler.
>
> The two operations are fundamentally different. One allows aggregate
> initialization, the other doesn't.
>
>
> > --------------
> > typedef struct {
> >    int x,y;
> > } Test;
> >
> > void main() {
>
> This is also not correct, and you should get a diagnostic message from
> a conforming compiler. The return type of main() has to be int.

MSVC allows this syntax as a convenience for times when you dont care
about the return value.

>
>
> >  // legal
> >  Test t1={1,2};
>
> This is an initialization.
>
>
> >
> >  // illegal
> >  Test t2;
> >  t2={1,2};
>
> This is an attempt to do an assignment.

Sure, technically they are different, but practically (as far as I
understand) they could be implemented in the compiler exactly the same
way, so I don't understand why the standard limited the "aggregate"
syntax to initialization than rather allowing it as a convenience for
all assignment statements, and I was hoping someone could clear that
up for me.

---
[ 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://www.jamesd.demon.co.uk/csc/faq.html                       ]