The following program exhibits different behavior with gcc vs. g++: dgregor$ cat t.c #include <stdio.h> int main() { int i; for( i = 0; i < 3; ) for( ; ; ({ i++; break; }) ) printf( "%d\n", i ); } With gcc, the break in the statement expression applies to the outer "for" loop, so we get just "0" as output: dgregor$ gcc t.c && ./a.out 0 with g++, the break in the statement expression applies to the inner "for" loop, so we get "0" "1" and "2" as the output: dgregor$ g++ t.c && ./a.out 0 1 2 g++ seems to have the right behavior here, and in any case g++ can't really be changed now: Qt's foreach macro depends on having "break" bind to the inner for loop.
Subject: Re: New: Break in increment expression of "for" statement inconsistent with g++ On Tue, 29 Jun 2010, doug dot gregor at gmail dot com wrote: > g++ seems to have the right behavior here, and in any case g++ can't really be > changed now: Qt's foreach macro depends on having "break" bind to the inner for > loop. Yes, the inconsistency should be fixed, but for both C and C++ I get "error: break statement not within loop or switch" if I only have one loop rather than nested loops, and break binding to the inner loop seems inconsistent with that error. The C standard specifically says that continue and break statements must appear in a loop body (or switch body, in the case of break); if you make break bind to the inner loop, you should also not have that error in the single loop case (the rule should change to allow additional positions in the loop outside its body). Whatever is done needs clearly defining and documenting (with testcases) for both break and continue, and including all relevant places in for, while, do-while and switch statements (I do not make a claim here as to exactly which places should allow break and so bind to the inner construct, and which should not and so bind to the outer construct if any).
Subject: Re: New: Break in increment expression of "for" statement inconsistent with g++ What does a break with a statement expression do for each frontend? Is it even valid to have a break there(without a statement expression)? If it is valid, what does each standard say about the break there? If they say the same thing then I say both frontends should behave the same but if the c standard says a break should apply to the outer one then we should follow that for statement expressions also. On Jun 29, 2010, at 9:20 AM, "doug dot gregor at gmail dot com" <gcc-bugzilla@gcc.gnu.org > wrote: > The following program exhibits different behavior with gcc vs. g++: > > dgregor$ cat t.c > #include <stdio.h> > > int main() > { > int i; > for( i = 0; i < 3; ) > for( ; ; ({ i++; break; }) ) > printf( "%d\n", i ); > } > > With gcc, the break in the statement expression applies to the outer > "for" > loop, so we get just "0" as output: > > dgregor$ gcc t.c && ./a.out > 0 > > with g++, the break in the statement expression applies to the inner > "for" > loop, so we get "0" "1" and "2" as the output: > > dgregor$ g++ t.c && ./a.out > 0 > 1 > 2 > > g++ seems to have the right behavior here, and in any case g++ can't > really be > changed now: Qt's foreach macro depends on having "break" bind to > the inner for > loop. > > > -- > Summary: Break in increment expression of "for" statement > inconsistent with g++ > Product: gcc > Version: 4.2.0 > Status: UNCONFIRMED > Severity: normal > Priority: P3 > Component: c > AssignedTo: unassigned at gcc dot gnu dot org > ReportedBy: doug dot gregor at gmail dot com > > > http://gcc.gnu.org/bugzilla/show_bug.cgi?id=44715 >
Subject: Re: Break in increment expression of "for" statement inconsistent with g++ On Tue, 29 Jun 2010, pinskia at gmail dot com wrote: > What does a break with a statement expression do for each frontend? Is > it even valid to have a break there(without a statement expression)? The relevant contexts have expressions, so without statement expressions it's not possible to have break there. The C standard (I haven't checked C++) requires break (and continue, which probably has much the same issue) to be in a loop or switch body - but being elsewhere in the loop than its body isn't possible in standard C anyway. When I was fixing statement expression issues with jumps, and defining exactly what was permitted (bug 772), I didn't think of this particular issue.
(In reply to comment #3) > Subject: Re: Break in increment expression of "for" statement > inconsistent with g++ > > On Tue, 29 Jun 2010, pinskia at gmail dot com wrote: > > > What does a break with a statement expression do for each frontend? Is > > it even valid to have a break there(without a statement expression)? > > The relevant contexts have expressions, so without statement expressions > it's not possible to have break there. The C standard (I haven't checked > C++) requires break (and continue, which probably has much the same issue) > to be in a loop or switch body - but being elsewhere in the loop than its > body isn't possible in standard C anyway. When I was fixing statement > expression issues with jumps, and defining exactly what was permitted (bug > 772), I didn't think of this particular issue. > As i said in the clang bug tracker who triggered this issue initially : Here is what the c++ standard says : "The break statement shall occur only in an iteration-statement or a switch statement and causes termination of the smallest enclosing iteration-statement or switch statement; control passes to the statement following the terminated statement, if any." So the break (if the expression statement extension is activated) is considered in the inner loop with this extension. And now here is what the c99 standard says : "A break statement shall appear only in or as a switch body or loop body" But in C, the loop body does not contain the expression statement. So the break applie only to the outer loop in C. The result is that gcc is correct in this behavior. C++ and C should differ in this matter.
*** Bug 49779 has been marked as a duplicate of this bug. ***
Author: jakub Date: Wed Jan 23 14:41:16 2019 New Revision: 268188 URL: https://gcc.gnu.org/viewcvs?rev=268188&root=gcc&view=rev Log: PR c/44715 * cp-gimplify.c (genericize_cp_loop): Call begin_bc_block only after genericizing cond and incr expressions. * doc/extend.texi: Document break and continue behavior in statement expressions. * c-c++-common/pr44715.c: New test. Added: trunk/gcc/testsuite/c-c++-common/pr44715.c Modified: trunk/gcc/ChangeLog trunk/gcc/cp/ChangeLog trunk/gcc/cp/cp-gimplify.c trunk/gcc/doc/extend.texi trunk/gcc/testsuite/ChangeLog
Should be fixed for GCC 9+.
*** Bug 90617 has been marked as a duplicate of this bug. ***