There's a clause I was never sure I understood the point of but I think it exists to forbid the following initialization:

int main(void) {
int x = ( (x = 1), 2);
}

In fact the clause is as follows:

No initializer shall attempt to provide a value for an object not contained within the entity being
initialized.

https://cigix.me/c17#6.7.9.p2

And it's not even clear it forbids int x = ( (x = 1), 2);. It may be only about forbidding int t[2] = { ( (t[1] = 1), 2), 3 };, or something else, who knows?

ISO/IEC 9899:2017

@void_friend I don't think that's what it's doing at all. Those are not "providing a value for an object" but simply assignment expressions. Rather, the confusing clause is related to how iteration of the current object/next subobject works when braces are misleading.

For example you can initialize

struct foo {
int x[2];
int y;
}

with { {1, 2}, 3 } or { 1, 2, 3 }

but not with { {1, 2, 3} }.

@void_friend what does the comma operator even do here given that the type being assigned to is an int?

@gsuberland It is, as you say, a comma operator, the thing that builds an expression e1, e2 from two expressions e1 and e2 with a precedence I am unsure of.

The comma that appears when initializing a compound type, or when applying a function of several arguments, is NOT a comma operator. If it were C++ and you overloaded the comma operator, these things would still behave as they did.

e1, e2 evaluates e1, discards the result, sequence point, evaluates e2 and yields whatever that yields.

@void_friend thanks.

and... sigh. I hate these weird syntax shenanigans.

@void_friend @gsuberland So which clause would forbid that initialization? I gotta admit I'd have thought the sequence point in your example would make this work (albeit in a convoluted fashion), assigning 1 then 2 to x. 🤔
@laomaiweng @gsuberland The initial example may have unspecified behavior, leaving x containing either 1 or 2. But it's not really conclusive, because https://cigix.me/c17#6.7.9.p23 is only about the initialization list expressions with respect to each other, not with respect to the initializations. Also I would like to point out that there are people that argue that (starting with x==0, the expression (0, (x*=2), 0) + (0, x++, 0) has UB (rather than leaving x in an unspecified state of either 1 or 2). I never understood these people's argument but by the same token, the first example in this thread would be UB.
ISO/IEC 9899:2017