Optimization Level -O2 in gcc

Discussion in 'C Programming' started by felipemartinsss, Jan 11, 2009.

  1. Hi Everybody.
    I have a problem with the flag -O2 and I would like to know why this
    problem is ocurring.
    I have the following code:

    #include <stdio.h>
    int f3nPlus1 (int n, int count);

    int main(void) {
    /* Declaração de variáveis */
    int n = 0;
    int maximumCycle = 0;
    int begin = 0;
    int end = 0;
    int temp = 0;
    FILE *filePtr;

    /* Código */

    filePtr = fopen("a.in", "r");

    if (filePtr) {
    while (!feof(filePtr)) {
    fscanf(filePtr, "%d%d\n", &begin, &end);
    /*printf ("begin: %d\n", begin);
    printf ("end: %d\n", end);*/
    for (n = begin; n <= end; n++) {
    temp = f3nPlus1( n, 0 );
    /*printf ("temp: %d\n", temp);*/
    if (temp > maximumCycle) {
    maximumCycle = temp;
    }

    }
    printf( "%d %d %d\n", begin, end, maximumCycle );
    temp = 0;
    maximumCycle = 0;

    }
    fclose(filePtr);

    } else {
    printf ("Arquivo nao pode ser aberto.\n");
    }
    return 0;
    }

    int f3nPlus1( int n, int count ) {
    if( n == 1 ) {
    return count + 1;
    } else {
    if(n % 2 != 0) {
    n = 3 * n + 1;
    f3nPlus1 ( n , count + 1);
    } else {
    n = n / 2;
    f3nPlus1 ( n , count + 1);
    }
    }
    }


    When I compile the code with gcc -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    pipe -ansi, everything's ok.
    But, when I compile with gcc -O2 -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    pipe -ansi, the execution give me wrong answers.

    The contents of the file a.in are:
    1 10
    100 200
    900 1000
    1 10
    1 11
    12 13
    1 10
    100 200
    201 210
    900 1000

    Thanks for the attention!
     
    felipemartinsss, Jan 11, 2009
    #1
    1. Advertising

  2. felipemartinsss

    Eric Sosman Guest

    felipemartinsss wrote:
    > Hi Everybody.
    > I have a problem with the flag -O2 and I would like to know why this
    > problem is ocurring.
    > I have the following code:
    > [...]
    > while (!feof(filePtr)) {


    This is not the problem you asked about, but it is
    another error you will eventually need to fix. Please
    see Question 12.2 in the comp.lang.c Frequently Asked
    Questions (FAQ) list at <http://www.c-faq.com/>.

    > [...]
    > int f3nPlus1( int n, int count ) {
    > if( n == 1 ) {
    > return count + 1;
    > } else {
    > if(n % 2 != 0) {
    > n = 3 * n + 1;
    > f3nPlus1 ( n , count + 1);
    > } else {
    > n = n / 2;
    > f3nPlus1 ( n , count + 1);
    > }
    > }
    > }


    Here's the immediate problem: When n != 1, what value does
    f3nPlus1() return?

    --
    Eric Sosman
    lid
     
    Eric Sosman, Jan 11, 2009
    #2
    1. Advertising

  3. felipemartinsss

    Flash Gordon Guest

    felipemartinsss wrote:
    > Hi Everybody.
    > I have a problem with the flag -O2 and I would like to know why this
    > problem is ocurring.
    > I have the following code:


    <snip>

    > temp = f3nPlus1( n, 0 );


    You use the value returned by f3nPlus1

    <snip>

    > int f3nPlus1( int n, int count ) {
    > if( n == 1 ) {
    > return count + 1;


    You return a value in this situation...

    > } else {



    However, where is the returned value if you enter this else instead?

    > if(n % 2 != 0) {
    > n = 3 * n + 1;
    > f3nPlus1 ( n , count + 1);
    > } else {
    > n = n / 2;
    > f3nPlus1 ( n , count + 1);
    > }
    > }
    > }




    > When I compile the code with gcc -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, everything's ok.
    > But, when I compile with gcc -O2 -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, the execution give me wrong answers.


    Try adding the following options "-ansi -pedantic -Wall -Wextra"
    Read the man/info/other documentation for gcc to understand what they do.
    --
    Flash Gordon
     
    Flash Gordon, Jan 11, 2009
    #3
  4. felipemartinsss

    James Kuyper Guest

    felipemartinsss wrote:
    ....
    > When I compile the code with gcc -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, everything's ok.
    > But, when I compile with gcc -O2 -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, the execution give me wrong answers.


    It would make our task a lot easier if you would tell us

    a) what you think the right answers should be.
    b) what the wrong answers were that your program gave to you.
     
    James Kuyper, Jan 11, 2009
    #4
  5. felipemartinsss <> writes:
    > I have a problem with the flag -O2 and I would like to know why this
    > problem is ocurring.
    > I have the following code:
    >
    > #include <stdio.h>
    > int f3nPlus1 (int n, int count);

    [snip]
    > temp = f3nPlus1( n, 0 );
    > /*printf ("temp: %d\n", temp);*/
    > if (temp > maximumCycle) {
    > maximumCycle = temp;
    > }

    [snip]
    > int f3nPlus1( int n, int count ) {
    > if( n == 1 ) {
    > return count + 1;
    > } else {
    > if(n % 2 != 0) {
    > n = 3 * n + 1;
    > f3nPlus1 ( n , count + 1);
    > } else {
    > n = n / 2;
    > f3nPlus1 ( n , count + 1);
    > }
    > }
    > }
    >
    > When I compile the code with gcc -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, everything's ok.
    > But, when I compile with gcc -O2 -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > pipe -ansi, the execution give me wrong answers.


    (The -lm, -lcrypt, and -pipe options are irrelevant.)

    If a program behaves differently under different optimization options,
    it's likely because the program exhibits undefined or unspecified
    behavior.

    In this case, there's one problem in your code that can easily be
    detected by increasing the warning level. Compiling with
    "gcc -c -ansi -pedantic -Wall -Wextra" gives me:

    c.c: In function 'f3nPlus1':
    c.c:55: warning: control reaches end of non-void function

    You're not returning a value from f3nPlus1, but you're using the
    value in main. Your recursive calls to f3nPlus1 just call it and
    discard the result; you need to add a "return". (Speculation:
    at -O0, it happens to return the value of the last expression
    evaluated; at -O2, the code is rearranged so this doesn't happen.
    But this kind of speculation isn't all that useful in most cases;
    the it's easier to just fix the bug than to spend time analyzing
    the symptoms.)

    Turning on optimization causes the compiler to perform more analysis,
    which can often let it detect more problems. Compiling with "gcc
    -c -ansi -pedantic -Wall -Wextra -O3" gives me:

    c.c: In function 'main':
    c.c:19: warning: ignoring return value of 'fscanf', declared with attribute warn_unused_result
    c.c: In function 'f3nPlus1':
    c.c:55: warning: control reaches end of non-void function

    You're calling fscanf() and ignoring its result. It can detect
    input errors for you, but you're throwing away that information.
    You should (almost) always check the result returned by any standard
    function, at least when you're dealing with a file you've opened --
    yes, even fclose().

    Note that the details are specific to gcc, but the same general
    approach is applicable to most compilers.

    Some more things I noticed:

    "while (!feof(filePtr))" is not the right way to write an input loop.
    feof() becomes true *after* you've tried and failed to read beyond
    the end of the file. I haven't tried running your program or
    analyzing it in any great detail, but my guess is that your last
    call to fscanf() at the end of the input will fail, but you'll go
    ahead and use the values of begin and end anyway, values that are
    probably left over from the previous call to fscanf. Recommended
    reading: section 12 of the comp.lang.c FAQ, <http://www.c-faq.com/>;
    question 12.2 seems particularly relevant. Furthermore, if there's
    an input error, ferror() becomes true but feof() doesn't; in that
    case, you'll probably have an infinite loop.

    Style points: Please don't use tab characters in code posted to
    Usenet. I've seen articles in which some news software somewhere
    quietly eliminated all the leading tab characters, leaving all
    the code unindented. And tab stops are typicall set to 8 columns;
    personally, I find 8-column indentation to be too deep.

    Several of the variables that you declare at the top of main()
    could be declared inside the blocks that use them. For example,
    begin, end, and temp could be declared inside the while loop.

    It's likely that others will notice problems that I missed.

    --
    Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    Nokia
    "We must do something. This is something. Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
     
    Keith Thompson, Jan 11, 2009
    #5
  6. On 11 jan, 14:04, Keith Thompson <> wrote:
    > felipemartinsss <> writes:
    > > I have a problem with the flag -O2 and I would like to know why this
    > > problem is ocurring.
    > > I have the following code:

    >
    > > #include <stdio.h>
    > > int f3nPlus1 (int n, int count);

    > [snip]
    > > temp = f3nPlus1( n, 0 );
    > > /*printf ("temp: %d\n", temp);*/
    > > if (temp > maximumCycle) {
    > > maximumCycle = temp;
    > > }

    > [snip]
    > > int f3nPlus1( int n, int count ) {
    > > if( n == 1 ) {
    > > return count + 1;
    > > } else {
    > > if(n % 2 != 0) {
    > > n = 3 * n + 1;
    > > f3nPlus1 ( n , count + 1);
    > > } else {
    > > n = n / 2;
    > > f3nPlus1 ( n , count + 1);
    > > }
    > > }
    > > }

    >
    > > When I compile the code with gcc -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > > pipe -ansi, everything's ok.
    > > But, when I compile with gcc -O2 -o f3nPlus1 f3nPlus1.c -lm -lcrypt -
    > > pipe -ansi, the execution give me wrong answers.

    >
    > (The -lm, -lcrypt, and -pipe options are irrelevant.)
    >
    > If a program behaves differently under different optimization options,
    > it's likely because the program exhibits undefined or unspecified
    > behavior.
    >
    > In this case, there's one problem in your code that can easily be
    > detected by increasing the warning level. Compiling with
    > "gcc -c -ansi -pedantic -Wall -Wextra" gives me:
    >
    > c.c: In function 'f3nPlus1':
    > c.c:55: warning: control reaches end of non-void function
    >
    > You're not returning a value from f3nPlus1, but you're using the
    > value in main. Your recursive calls to f3nPlus1 just call it and
    > discard the result; you need to add a "return". (Speculation:
    > at -O0, it happens to return the value of the last expression
    > evaluated; at -O2, the code is rearranged so this doesn't happen.
    > But this kind of speculation isn't all that useful in most cases;
    > the it's easier to just fix the bug than to spend time analyzing
    > the symptoms.)
    >
    > Turning on optimization causes the compiler to perform more analysis,
    > which can often let it detect more problems. Compiling with "gcc
    > -c -ansi -pedantic -Wall -Wextra -O3" gives me:
    >
    > c.c: In function 'main':
    > c.c:19: warning: ignoring return value of 'fscanf', declared with attribute warn_unused_result
    > c.c: In function 'f3nPlus1':
    > c.c:55: warning: control reaches end of non-void function
    >
    > You're calling fscanf() and ignoring its result. It can detect
    > input errors for you, but you're throwing away that information.
    > You should (almost) always check the result returned by any standard
    > function, at least when you're dealing with a file you've opened --
    > yes, even fclose().
    >
    > Note that the details are specific to gcc, but the same general
    > approach is applicable to most compilers.
    >
    > Some more things I noticed:
    >
    > "while (!feof(filePtr))" is not the right way to write an input loop.
    > feof() becomes true *after* you've tried and failed to read beyond
    > the end of the file. I haven't tried running your program or
    > analyzing it in any great detail, but my guess is that your last
    > call to fscanf() at the end of the input will fail, but you'll go
    > ahead and use the values of begin and end anyway, values that are
    > probably left over from the previous call to fscanf. Recommended
    > reading: section 12 of the comp.lang.c FAQ, <http://www.c-faq.com/>;
    > question 12.2 seems particularly relevant. Furthermore, if there's
    > an input error, ferror() becomes true but feof() doesn't; in that
    > case, you'll probably have an infinite loop.
    >
    > Style points: Please don't use tab characters in code posted to
    > Usenet. I've seen articles in which some news software somewhere
    > quietly eliminated all the leading tab characters, leaving all
    > the code unindented. And tab stops are typicall set to 8 columns;
    > personally, I find 8-column indentation to be too deep.
    >
    > Several of the variables that you declare at the top of main()
    > could be declared inside the blocks that use them. For example,
    > begin, end, and temp could be declared inside the while loop.
    >
    > It's likely that others will notice problems that I missed.
    >
    > --
    > Keith Thompson (The_Other_Keith) <http://www.ghoti.net/~kst>
    > Nokia
    > "We must do something. This is something. Therefore, we must do this."
    > -- Antony Jay and Jonathan Lynn, "Yes Minister"


    Hi,
    thanks for all! =]
     
    felipemartinsss, Jan 11, 2009
    #6
  7. felipemartinsss

    CBFalconer Guest

    felipemartinsss wrote:
    >
    > I have a problem with the flag -O2 and I would like to know why
    > this problem is ocurring. I have the following code:
    >

    .... snip ...
    >
    > if (filePtr) {
    > while (!feof(filePtr)) {
    > fscanf(filePtr, "%d%d\n", &begin, &end);


    feof is not a suitable mechanism. It only is set after an input
    routine has failed because of EOF.

    --
    [mail]: Chuck F (cbfalconer at maineline dot net)
    [page]: <http://cbfalconer.home.att.net>
    Try the download section.
     
    CBFalconer, Jan 12, 2009
    #7
  8. On 11 jan, 12:03, Eric Sosman <> wrote:
    > felipemartinsss wrote:
    > > Hi Everybody.
    > > I have a problem with the flag -O2 and I would like to know why this
    > > problem is ocurring.
    > > I have the following code:
    > > [...]
    > > while (!feof(filePtr)) {

    >
    > This is not the problem you asked about, but it is
    > another error you will eventually need to fix. Please
    > see Question 12.2 in the comp.lang.c Frequently Asked
    > Questions (FAQ) list at <http://www.c-faq.com/>.
    >
    > > [...]
    > > int f3nPlus1( int n, int count ) {
    > > if( n == 1 ) {
    > > return count + 1;
    > > } else {
    > > if(n % 2 != 0) {
    > > n = 3 * n + 1;
    > > f3nPlus1 ( n , count + 1);
    > > } else {
    > > n = n / 2;
    > > f3nPlus1 ( n , count + 1);
    > > }
    > > }
    > > }

    >
    > Here's the immediate problem: When n != 1, what value does
    > f3nPlus1() return?
    >
    > --
    > Eric Sosman
    >


    Yes. It was not working very well, so I couldn't continue. But I was
    not receiving the warnings, with the option -Wall I changed
    the code and solved the problem.
    Thanks for All again.
     
    felipemartinsss, Jan 12, 2009
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Will Ware
    Replies:
    1
    Views:
    278
    Will Ware
    Jan 2, 2006
  2. pabbu
    Replies:
    8
    Views:
    772
    Marc Boyer
    Nov 7, 2005
  3. compiler_newbie

    Question on gcc -O3 optimization (bug or feature)

    compiler_newbie, Jun 11, 2008, in forum: C Programming
    Replies:
    9
    Views:
    643
    Keith Thompson
    Jun 13, 2008
  4. AJ

    gcc power optimization

    AJ, Nov 7, 2008, in forum: C Programming
    Replies:
    2
    Views:
    283
    Flash Gordon
    Nov 7, 2008
  5. Ravikiran

    Zero Optimization and Sign Optimization???

    Ravikiran, Nov 17, 2008, in forum: C Programming
    Replies:
    22
    Views:
    904
    Thad Smith
    Nov 24, 2008
Loading...

Share This Page