Thread: An interesting bug on GCC 9 and above

  1. #1
    Registered User
    Join Date
    Feb 2019
    Posts
    1,078

    An interesting bug on GCC 9 and above

    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      unsigned int a; 
      unsigned int b;
      unsigned int c;
    
      c = 0;
      for ( a = 0; a < 10; a++ ) 
        for ( b = 0; b < 2; b++ ) 
        {
          c++; 
               
          printf( "a=%u, c=%u\n", a, c );
    
          if ( c < a ) 
            return 123; 
        }
    
      return 0; 
    }
    On GCC 9+ this code will print on 3 lines and return 123 if you compile with any optimization options (any of -O options, except, of course -O0). As you can see there is no overflow and c will never be less than a. It should print 20 lines and return 0.

    Change the comparison to b < N, where N != 2, in the inner loop and will work correctly. Or change the variables to 'int' (signed) and will work correctly.

    This bug isn't present on GCC 8 and below.

  2. #2
    Registered User rstanley's Avatar
    Join Date
    Jun 2014
    Location
    New York, NY
    Posts
    1,106
    Quote Originally Posted by flp1969 View Post
    Code:
    #include <stdio.h>
    
    int main ( void )
    {
      unsigned int a; 
      unsigned int b;
      unsigned int c;
    
      c = 0;
      for ( a = 0; a < 10; a++ ) 
        for ( b = 0; b < 2; b++ ) 
        {
          c++; 
               
          printf( "a=%u, c=%u\n", a, c );
    
          if ( c < a ) 
            return 123; 
        }
    
      return 0; 
    }
    On GCC 9+ this code will print on 3 lines and return 123 if you compile with any optimization options (any of -O options, except, of course -O0). As you can see there is no overflow and c will never be less than a. It should print 20 lines and return 0.

    Change the comparison to b < N, where N != 2, in the inner loop and will work correctly. Or change the variables to 'int' (signed) and will work correctly.

    This bug isn't present on GCC 8 and below.
    I am running gcc version 10.2.1, on Debian testing, and -O1, -O2, and -O3, as well as with no -O options, all with -std=c18, and the code runs as you expect it should, and all return 0.

    I cannot comment on this any further.

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    Well that's pretty weird.
    Compiler Explorer

    Lot's of compilers to choose from.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    May 2012
    Location
    Arizona, USA
    Posts
    945
    I'm on Linux Mint 19.3 with GCC 9.3.0, and I can confirm it happens for me too. I'm trying to find any undefined behavior in the code but can't so far. Definitely looks like a bug in GCC 9.

  5. #5
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Correction it did have the bug; I forgot to set optimize option on first test
    Code:
    gcc.exe (Rev5, Built by MSYS2 project) 10.3.0
    Tim S.
    Last edited by stahta01; 08-31-2021 at 01:36 PM. Reason: correction
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  6. #6
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    Very strange. You can even start c at 1000. Interesting how changing unsigned to int fixes it.
    Code:
    #include <stdio.h>
     
    int main()
    {
        unsigned a, b, c = 1000;
    
        for (a = 0; a < 5; ++a)
        {
            for (b = 0; b < 2; ++b)
            {
                ++c;
                printf("a=%u, c=%u\n", a, c);
                if (c < a)
                {
                    printf("Premature termination\n");
                    return 0;
                }
            }
        }
     
        printf("Normal termination\n");
        return 0; 
    }
    Last edited by john.c; 08-31-2021 at 01:45 PM.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  7. #7
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    I did not see the problem with "-Og" can anyone else confirm this?
    MSys2 GCC 10.3.0
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  8. #8
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    -Og enables optimizations that do not interfere with debugging.
    It would not include unrolling loops, which is at least part of what's happening here, albeit incorrectly.
    A little inaccuracy saves tons of explanation. - H.H. Munro

  9. #9
    Registered User
    Join Date
    May 2009
    Posts
    4,183
    Quote Originally Posted by john.c View Post
    -Og enables optimizations that do not interfere with debugging.
    It would not include unrolling loops, which is at least part of what's happening here, albeit incorrectly.
    That is my guess; but, I have found my guess are often wrong about which optimize option causes a GCC program bug/crash.

    Tim S.
    "...a computer is a stupid machine with the ability to do incredibly smart things, while computer programmers are smart people with the ability to do incredibly stupid things. They are,in short, a perfect match.." Bill Bryson

  10. #10
    Registered User
    Join Date
    Dec 2017
    Posts
    1,626
    I looked at the generated assembly (with -S) and it has unrolled the loop, but only for 3 iterations. However, just using -funroll-loops doesn't cause the problem.
    A little inaccuracy saves tons of explanation. - H.H. Munro

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Something interesting for you.
    By SlyMaelstrom in forum A Brief History of Cprogramming.com
    Replies: 22
    Last Post: 11-10-2005, 04:29 PM
  2. Interesting
    By Brian in forum A Brief History of Cprogramming.com
    Replies: 4
    Last Post: 08-20-2003, 10:21 AM
  3. Interesting Day
    By gnu-ehacks in forum A Brief History of Cprogramming.com
    Replies: 10
    Last Post: 02-23-2002, 08:49 AM
  4. Interesting..
    By Brian in forum A Brief History of Cprogramming.com
    Replies: 0
    Last Post: 01-28-2002, 12:41 PM

Tags for this Thread