Bug 56180 - Strange behaviour with optimization (using K&R C)
Summary: Strange behaviour with optimization (using K&R C)
Status: RESOLVED INVALID
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: 2013-02-02 08:59 UTC by Paulo Torrens
Modified: 2013-02-03 09:22 UTC (History)
1 user (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Paulo Torrens 2013-02-02 08:59:56 UTC
I'm writing a piece of code that needs to be on old K&R C style, and found a problem recently.

When using no optimization I get one behaviour, with -O1 I get another, and with -O2 I get *yet another* behaviour. Both GCC and CLang show the same behaviour (although GCC shows three "versions" of the results, and CLang shows only two).


There is probably something I did wrong in the code itself, I got the part of the program that showed the problem and placed it on a single test C file, which still showed the problem... although probably is some logic error of mine, the compiler shouldn't show different behaviours.




The source code [test.c]: http://pastebin.com/SS1JHH1n
The test file [test.psy]: http://pastebin.com/ejLqYaxH



I'm not sure what is the problem over here, so I decided to report. :)
Comment 1 Jakub Jelinek 2013-02-02 10:49:26 UTC
You should try your program e.g. under valgrind, or bother reading manual pages.
One obvious bug is e.g. that you really can't call ungetc more than once without an intervening read from the stream.
Comment 2 Jakub Jelinek 2013-02-02 11:15:22 UTC
And, even if ungetc works for more than one character (e.g. in glibc it will often work if you are calling ungetc with the characters that fgetc etc. returned from the stream, in reverse order, plus the one guaranteed unrelated ungetc),
the
        /* If we were just checking ahead, unget everything */
        while(j) {
          ungetc(buf[j], parser->file);
          j--;
        }
loop is calling ungetc first with an uninitialized byte (j is one above the last index stored).  There are various other issues in the program.
Comment 3 Paulo Torrens 2013-02-02 21:45:20 UTC
According to the man page here on Mac:

Only one character of push-back is guaranteed, but as long as there is sufficient memory, an effectively infinite amount of push-back is allowed.


And yeah, you are right (thank you!), that j was one byte ahead, but, still... shouldn't the behaviour be the same across optimization levels?
Comment 4 Jakub Jelinek 2013-02-03 09:22:05 UTC
When you were calling ungetc with uninitialized char, that is invoking undefined behavior, anything can happen at that point.