Bug 60809 - C99 struct initialiser with embedded self assignment
Summary: C99 struct initialiser with embedded self assignment
Status: SUSPENDED
Alias: None
Product: gcc
Classification: Unclassified
Component: c (show other bugs)
Version: 4.8.1
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2014-04-10 12:37 UTC by jimis
Modified: 2014-04-30 05:20 UTC (History)
0 users

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2014-04-30 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description jimis 2014-04-10 12:37:28 UTC
For the following code, which was a typo from my side (full example attached):

<pre>
        struct addrinfo query2 = {
                .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_STREAM,
                query2.ai_flags = AI_PASSIVE
        };
</pre>

1. A warning would be nice, something like "suggest parentheses around assignment"
2. What is the C99 mandated behaviour? I'm not sure GCC is behaving properly. Currently it sets ai_protocol to 1 because it is the next field after ai_socktype. But it also sets ai_flags to 1, which I'd expect to be 0 after the outer struct initialiser is executed.


See discussion, full example program and output, at http://gcc.gnu.org/ml/gcc-help/2014-04/msg00033.html
Comment 1 Marek Polacek 2014-04-10 14:01:04 UTC
I see nothing surprising here; an assignment expression has the value of the left operand after the assignment.  So we 1) set query2.ai_flags to AI_PASSIVE, 2) use this value to initialize .ai_protocol.

I'm not sure a warning here makes sense: an assignment-expression is perfectly valid initializer.
Comment 2 jimis 2014-04-10 14:10:34 UTC
(In reply to Marek Polacek from comment #1)
> I see nothing surprising here; an assignment expression has the value of the
> left operand after the assignment.  So we 1) set query2.ai_flags to
> AI_PASSIVE, 2) use this value to initialize .ai_protocol.

if the outer assignment runs last, shouldn't it overwrite the inner assignment? Then it should be equivalent to that:

<pre>
        struct addrinfo query3 = {
                .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_STREAM,
		1
</pre>

Which means that ai_flags should be 0.
Comment 3 Andreas Schwab 2014-04-10 14:24:35 UTC
6.7.9 Initialization
23 The evaluations of the initialization list expressions are indeterminately sequenced with respect to one another and thus the order in which any side effects occur is unspecified.
Comment 4 jimis 2014-04-10 16:33:44 UTC
Thanks Andreas, that's the reference I was looking for!

I guess since this code triggers unspecified behaviour, a warning would be even more needed. :-)
Comment 5 jimis 2014-04-10 18:37:20 UTC
Andreas: On a second thought, this paragraph only talks about the order *within* the initialisation list. But no matter of that order, the initialisation list is always evaluated to:

        {
                .ai_family = AF_UNSPEC,
                .ai_socktype = SOCK_STREAM,
                AI_PASSIVE
        };


The outer assignment to query2, should never set ai_flags, no matter what the side-effects of the inner assignments are. Am I thinking right?
Comment 6 jsm-csl@polyomino.org.uk 2014-04-29 21:43:17 UTC
I see nothing that says anything about the sequencing of side effects in 
initialization expressions with respect to the actual initialization 
itself, or parts thereof - either to require a particular sequencing, or 
to make it indeterminately sequenced or unsequenced.  That may mean it's 
implicitly unsequenced, but I'd suggest raising this with WG14.
Comment 7 Marek Polacek 2014-04-30 05:20:33 UTC
(In reply to joseph@codesourcery.com from comment #6)
> I see nothing that says anything about the sequencing of side effects in 
> initialization expressions with respect to the actual initialization 
> itself, or parts thereof - either to require a particular sequencing, or 
> to make it indeterminately sequenced or unsequenced.  That may mean it's 
> implicitly unsequenced, but I'd suggest raising this with WG14.

Thanks, I'll try to report it then; suspending for now.