Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Struct assignment.

24 views
Skip to first unread message

Andrew

unread,
Apr 19, 2010, 11:48:42 AM4/19/10
to
This works (where struct point is what you think it is):

struct point pt = {5,17};

But this fails:

struct point pt;
pt = {5,17};

I'm unsure why, and the inability to use the bracket syntax after pt is
declared irritates me. I seek enlightenment.

--

Andrew
--
comp.lang.c.moderated - moderation address: cl...@plethora.net -- you must
have an appropriate newsgroups line in your header for your mail to be seen,
or the newsgroup name in square brackets in the subject line. Sorry.

Keith Thompson

unread,
Apr 19, 2010, 1:22:21 PM4/19/10
to
Andrew <no...@none.com> writes:
> This works (where struct point is what you think it is):
>
> struct point pt = {5,17};
>
> But this fails:
>
> struct point pt;
> pt = {5,17};
>
> I'm unsure why, and the inability to use the bracket syntax after pt is
> declared irritates me. I seek enlightenment.

{5, 17} is specifically part of the syntax for initializers; it's not
an expression.

I think the idea is that restricting this kind of thing to a single
context makes things easier for the compiler. When it sees the
{5, 17}, it already knows what's going to be done with the result:
it's going to be copied into the object pt. If {5, 17} were a
valid expression, though, it could appear in many more contexts.
The compiler would probably have to create (and later destroy) a
temporary object to hold the value. Also, there's no indication of
what type it should be, since the type of an expression is almost
always determined by the expression itself, not by the context in
which it appears.

That's why C99 introduced compound literals. For the full details,
grab a copy of
<http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>
and read section 6.5.2.5. But for example, this is legal in C99:

struct point { int x; int y; };
struct point pt;
pt = (struct point){5, 17};

Note that ``(struct point){5, 17}'' is not a cast expression, even
though it resembles one, since ``{5, 17}'' still isn't an expression
so it can't be the operand of a cast.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"

Andrew

unread,
Apr 19, 2010, 2:04:12 PM4/19/10
to
On Mon, 19 Apr 2010 12:22:21 -0500 (CDT), Keith Thompson wrote:

> That's why C99 introduced compound literals. For the full details,
> grab a copy of
> <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>
> and read section 6.5.2.5. But for example, this is legal in C99:

I probably should have mentioned I'm using C99 in the first place, now that
I think of it.

> struct point { int x; int y; };
> struct point pt;
> pt = (struct point){5, 17};
>
> Note that ``(struct point){5, 17}'' is not a cast expression, even
> though it resembles one, since ``{5, 17}'' still isn't an expression
> so it can't be the operand of a cast.

This is *exactly* what I was looking for -- and the explanation of why it
works that way (and not the way I was trying) is interesting too. Many
thanks.

--

Andrew

mohangupta13

unread,
Jun 1, 2010, 5:56:49 PM6/1/10
to
On Apr 19, 10:22 pm, Keith Thompson <ks...@mib.org> wrote:

whats it if not a cast ? How do you distinguish between the two ?

even
> though it resembles one, since ``{5, 17}'' still isn't an expression
> so it can't be the operand of a cast.
>
> --
> Keith Thompson (The_Other_Keith) ks...@mib.org  <http://www.ghoti.net/~kst>
> Nokia
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"
> --

> comp.lang.c.moderated - moderation address: c...@plethora.net -- you must

Keith Thompson

unread,
Jun 1, 2010, 10:34:45 PM6/1/10
to
mohangupta13 <mohang...@gmail.com> writes:
> On Apr 19, 10:22 pm, Keith Thompson <ks...@mib.org> wrote:
[...]

>> That's why C99 introduced compound literals.  For the full details,
>> grab a copy of
>>     <http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf>
>> and read section 6.5.2.5.  But for example, this is legal in C99:
>>
>>     struct point { int x; int y; };
>>     struct point pt;
>>     pt = (struct point){5, 17};
>>
>> Note that ``(struct point){5, 17}'' is not a cast expression,
>
> whats it if not a cast ? How do you distinguish between the two ?

It's not a cast expression. It's a compound literal. Because,
as I wrote:

> even
>> though it resembles one, since ``{5, 17}'' still isn't an expression
>> so it can't be the operand of a cast.

The syntax for a cast-expression is, roughly (I'm deliberately
glossing over some details):

( type-name ) expression

The syntax for a compound literal is (again glossing over some details):

( type-name ) { initializer-list }

There is some similarity in that both start with a parenthesized
type-name that gives the type of the expression. But there is no
overlap between these two forms; an initializer-list enclosed in
{ and } cannot be an expression, so there's no possible ambiguity.

And you can be sure that the authors of the standard thought very
carefully about this.

--
Keith Thompson (The_Other_Keith) ks...@mib.org <http://www.ghoti.net/~kst>
Nokia
"We must do something. This is something. Therefore, we must do this."
-- Antony Jay and Jonathan Lynn, "Yes Minister"
--

James Kuyper

unread,
Jun 1, 2010, 10:35:00 PM6/1/10
to
On 06/01/2010 05:56 PM, mohangupta13 wrote:
> On Apr 19, 10:22�pm, Keith Thompson<ks...@mib.org> wrote:
...

>> Note that ``(struct point){5, 17}'' is not a cast expression,
>
> whats it if not a cast ? ...

There are two ways to form a compound literal described in section 6.5.2p1:

( type-name ) { initializer-list }
( type-name ) { initializer-list , }

The details of how to interpret such expressions are given in section
6.5.2.5.

The first three parts of a compound literal are the same as the first
three parts of the second grammar production for a cast-expression, as
described in section 6.5.4:

unary-expression
( type-name ) cast-expression

The way to distinguish them is by looking at the remaining parts.

> ... How do you distinguish between the two ?

If the thing that follows "( type-name )" is a unary-expression, then
you can apply the first grammar production to identify it as also being
a cast-expression. You then can use the second grammar production to
identify the entire thing as itself being a cast-expression.

If the thing that follows "( type-name )" is a initializer-list
surrounded by a matched pair of curly brackets (optionally including a
final comma before the right curly bracket), then what you've got is a
compound literal.

Alan Curry

unread,
Jun 2, 2010, 8:05:56 PM6/2/10
to
In article <clcm-2010...@plethora.net>,

Keith Thompson <ks...@mib.org> wrote:
>
>There is some similarity in that both start with a parenthesized
>type-name that gives the type of the expression. But there is no
>overlap between these two forms; an initializer-list enclosed in
>{ and } cannot be an expression, so there's no possible ambiguity.
>
>And you can be sure that the authors of the standard thought very
>carefully about this.

Or at least put the final grammar through yacc once before publishing, and
paid attention to the number of conflicts.

--
Alan Curry

0 new messages