Bug 98345 - Different behaviour of gcc Versions (<=8, >=9)
Summary: Different behaviour of gcc Versions (<=8, >=9)
Status: RESOLVED DUPLICATE of bug 90617
Alias: None
Product: gcc
Classification: Unclassified
Component: c++ (show other bugs)
Version: unknown
: P3 normal
Target Milestone: ---
Assignee: Not yet assigned to anyone
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2020-12-17 12:38 UTC by Peter Budek
Modified: 2020-12-17 13:58 UTC (History)
2 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2020-12-17 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Peter Budek 2020-12-17 12:38:52 UTC
The following (strange) construction seems to behave different
in Versions <=8 and >=9:
for( ... ; ... ; ... )
	for(... ; ... ; break)...
Versions <=8 cancel the inner loop, Versions >=9 the outer loop.

The real problem is, that a similar construction is used in QT4's
implementation of foreach() (Qt/qglobal.h and QtCore/qglobal.h).

Compiling old QT projects with a version >=9 will fail, if
foreach is used.
Comment 1 Martin Liška 2020-12-17 13:12:42 UTC
Can you please attach a self-contained test-case one can compile?
Comment 2 Jakub Jelinek 2020-12-17 13:27:07 UTC
Most likely PR44715.  Just use new Qt or fix the old one.
Comment 3 Jakub Jelinek 2020-12-17 13:28:14 UTC
And more details about it are in PR90617.

*** This bug has been marked as a duplicate of bug 90617 ***
Comment 4 Peter Budek 2020-12-17 13:41:07 UTC
The requested test-case:

#include <iostream>
#include <QtCore/QList>

int main(int argc, char *argv[])
{
   QList<int> l ;
 
   l.append(1) ;    
   l.append(2) ;
   l.append(3) ;
   foreach(int i, l) std::cout << i << std::endl ;  
   
   return(0) ;
}

The result is '1' with gcc 10.2.0 (not 1 2 3).
I found this compiling qucs (http://qucs.sourceforge.net/index.html).

patching qt helps:
+++ qt-everywhere-opensource-src-4.8.7/src/corelib/global/qglobal.h     2020-12-17 10:46:30.000000000 +0100
@@ -2496,9 +2496,9 @@
 #define Q_FOREACH(variable, container)                                \
 for (QForeachContainer<__typeof__(container)> _container_(container); \
      !_container_.brk && _container_.i != _container_.e;              \
      __extension__  ({ ++_container_.brk; ++_container_.i; }))                       \
-    for (variable = *_container_.i;; __extension__ ({--_container_.brk; break;}))
+    for (variable = *_container_.i;!_container_.brk; __extension__ ({--_container_.brk;}))
 
 #else
 
 struct QForeachContainerBase {};
Comment 5 Jakub Jelinek 2020-12-17 13:58:31 UTC
Old Qt was relying on a GCC bug (as can be seen from the fact that
void
foo ()
{
  for (;; ({ break; }))
    ;
}
has been rejected since forever).  It wasn't rejected in the for nested in another for, because it was expected to bind in that case to the outer loop, but due to a bug was bound to the inner loop.
This has been fixed in GCC9 and newer.