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
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.
(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.
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.
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. :-)
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?
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.
(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.