https://gcc.gnu.org/bugzilla/show_bug.cgi?id=121563
--- Comment #8 from Christopher Bazley <Chris.Bazley at arm dot com> --- (In reply to Jakub Jelinek from comment #1) > In the f2 case, you are declaring y, then forward declaring another y and > declaring another y. That is the same error as if you do void f2a (int y, > int y);. This reminded me so much of an example in my paper: void tester(int x; char data[x], int x, int y; int z; char data[y][z], int y, int z); If the only meaning of the semicolon were "the previous declaration was a forward parameter declaration" then it should be possible to interleave forward declarations and "real" declarations (as in the above example). I think the fact that semicolon instead means "all previous declarations were forward parameter declarations" is a source of confusion, because comma-separated declarations following a semicolon may appear to be "real" parameter declarations instead of forward parameter declarations. With a fixed limit of two clauses, there is initial ambiguity but that is resolved upon encountering the first semicolon or closing bracket. With an unlimited number of clauses, the ambiguity persists until the last semicolon or closing bracket but (and there is no way of predicting which is the last semicolon).