Help: Is this a bug in my compiler?

  • Thread starter mehrdad ghassempoory
  • Start date
A

Anand Hariharan

Or anything else it wants to be.  The behavior is undefined.  It isn't
even guaranteed, in at least some cases, to compile.

Could you post an example having identical characteristics that would
fail to compile? By "identical characteristics" I mean a program that
(only) tries to modify an object more than once without an intervening
sequence point, and not introduce other characteristics.
 
S

Seebs

Could you post an example having identical characteristics that would
fail to compile? By "identical characteristics" I mean a program that
(only) tries to modify an object more than once without an intervening
sequence point, and not introduce other characteristics.

"Would" fail to compile is pretty strong.

"That a compiler could choose to reject if it wanted to", though, is easy:

int main(void) { int i = 0; i = i++; return 0; }

So far as I can tell, current consensus is that, since the compiler can
establish conclusively that undefined behavior would occur if the program
were executed, it's not required to generate an output file. I think most
do, but "gcc -Werror" might be a compiler that would reject programs
like this. (And some other programs, some of which were confirming code,
but hey, babies and bathwater, right?)

-s
 
K

Keith Thompson

Seebs said:
"Would" fail to compile is pretty strong.

"That a compiler could choose to reject if it wanted to", though, is easy:

int main(void) { int i = 0; i = i++; return 0; }

So far as I can tell, current consensus is that, since the compiler can
establish conclusively that undefined behavior would occur if the program
were executed, it's not required to generate an output file. I think most
do, but "gcc -Werror" might be a compiler that would reject programs
like this. (And some other programs, some of which were confirming code,
but hey, babies and bathwater, right?)

gcc 4.3.3 with no additional options doesn't even produce a diagnostic
for that program. Using "-Wall" causes a warning; "-Werror" turns the
warning into an error -- but as you imply "gcc -Wall -Werror" is
non-conforming, rejecting some conforming programs.

Modifying an object more than once between sequence points is not a
constraint violation. Compilers are not required to reject or
diagnose such programs, though they can choose to do so.
 
P

Phil Carmody

Keith Thompson said:
In at least some cases, GNU autoconf assumes that, if the compiler
produces any output on stderr, the compilation failed. Specifically,
it checks for the existence of headers by compiling a small generated
program that includes those headers; if the compilation generates
anything on stderr, autoconf assumes the headers don't exist.

The simple solution is to drop autoconf in a deep hole; something
which should have been done decades ago.

Phil
 
S

Seebs

I've never heard such rubbish. What hole could possibly be deep
enough?

The depth of hole you need depends on sizeof(char), let me just compile
a quick test program and get back to you on that.

-s
 
P

Phil Carmody

Richard Heathfield said:
I've never heard such rubbish. What hole could possibly be deep
enough?

Hopefully the Large Hadron Compiler will 'optimise' it for size
sufficiently.

Phil
 
N

Nick Keighley

Yes, you can.  Thousands of lines of them.


In context:  We have a build system which builds packages with output
and errors into log files.  We then display the last N lines of a log
file on a failure.

I'd say your build system was broken. I'd *much* rather see the
beginning of a compilation log than the end. In fact once I've seen
about three incorrect diagnostics (because the compiler got confused
by an earlier error) I give up and run the compilation again (with the
errors found so far, fixed!)
 Which means that the current behavior ensures that
a missing header cannot be diagnosed without going and looking at the
full log file, while the corrected behavior would allow it to be diagnosed
instantly.

no argument. A missing header file is too serious to continue.
 
S

Seebs

I'd say your build system was broken. I'd *much* rather see the
beginning of a compilation log than the end. In fact once I've seen
about three incorrect diagnostics (because the compiler got confused
by an earlier error) I give up and run the compilation again (with the
errors found so far, fixed!)

The beginning is, with rare exceptions, several hundred lines of autoconf poo.

(I believe that's the official term.)

-s
 
N

Nick

Nick Keighley said:
no argument. A missing header file is too serious to continue.

It also makes it clear to you what the problem is. #include <stdio,h>
is far too easy a mistake to make and sometimes the diagnostics don't
make you realise what the problem is.
 
R

Richard Tobin

junk.c:6: warning: operation on 'i' may be undefined

In gcc 5, the -Wall warnings will be default warnings and the -Wextra
warnings will be promoted to -Wall.

That wouldn't be quite right. The code in question is just wrong;
even if some compiler specifies the order of evaluation, no-one should
rely on it in portable code (and the fact that they're compiling it in
gcc as well as the putative compiler shows that it's meant to be
portable). It should be a plain error. And it certainly shouldn't be
controlled by the same switch that enables diagnostics for things that
are commonly non-errors, such as conditionals that are always true.

-- Richard
 
R

Richard Tobin

Though I agree (mostly)
that once you've encountered a missing header there's not much point
in continuing.
[/QUOTE]
I have never yet had a case where continuing was rewarding. I have had
hundreds where sorting through the irrelevant error messages was a pain
or caused me trouble.

But you could blame that on the compiler's poor error recovery. It
could behave more laxly after a missing include, for example assuming
that an undeclared name was a type if doing so would make an
incomprehensible statement into a legal declaration.

It's difficult to do good error recovery, but it seems to me that
compilers used to be better at this sort of thing; perhaps because
languages were simpler, or perhaps because when your program was on
punched cards it was important to correct as many errors as possible
in one go.

-- Richard
 
S

Seebs

That's true of course. But the first comment is really more
enlightening. It's undefined *because* a compiler might reasonably
perform the calculation in one of several natural orders. It's not
some unmotivated rule to trap the unwary. Though the standard allows
the proverbial nasal demons, they are merely an artefact of the way
the standard authors decided to handle these cases.

That would justify "unspecified". Undefined behavior is a stronger term.

I seem to recall being told that there have been systems in which naive
instruction scheduling could result in spectacularly weird behavior from
things like the "i = ++i" example, because the generated code could end
up copying registers which had been partially but not completely updated.
(There have been systems in which you could load a 32-bit register 16
bits at a time -- if your scheduler assumed that code didn't have overlapping
side-effects like this, you could end up with something copying a value which
was in the middle of being updated, which could produce very weird results.)

I've seen one of these once, although I no longer remember the details.
I believe it was code to the effect of:

i = ++i % 4;

and produced a sequence something like
1 5 65 513

It was, to put it mildly, pretty weird. (I probably have the details
of the sequence wrong, but it was something of that nature; it was not
particularly obvious.)

-s
 
R

Richard Tobin

i=1;
i=3 + i++;
The value of i is either 4 or 5 due to different compiler!
[/QUOTE]
Yes, you are likely to get one of those two answers on many compilers you
are likely to encounter.

However, the value of i (and, in fact, the entire state of the program and
the computer it's running on) is undefined upon executing that statement.

That's true of course. But the first comment is really more
enlightening. It's undefined *because* a compiler might reasonably
perform the calculation in one of several natural orders. It's not
some unmotivated rule to trap the unwary. Though the standard allows
the proverbial nasal demons, they are merely an artefact of the way
the standard authors decided to handle these cases.

-- Richard
 
K

Keith Thompson

That wouldn't be quite right.
[snip]

You're (at least) the second person who's missed the part after the
control-L:

In my newsreader, a control-L (formfeed) causes it to display "Next
page..." in bold; I can then press <space> to read the text that
follows the control-L. Other newsreaders may behave differently.
 
R

Richard Tobin

Seebs said:
I seem to recall being told that there have been systems in which naive
instruction scheduling could result in spectacularly weird behavior from
things like the "i = ++i" example, because the generated code could end
up copying registers which had been partially but not completely updated.

This is quite likely true. And I think it's reasonable for
standardisers to say "since this might be done either of these
reasonable ways, we might as well make it completely undefined",
because that allows for the unanticipated. But the *motivation* is
the different obvious orderings, and I think that's the most effective
way to explain it. The elaboration can be relegated to a footnote[1].

[1] Though they are rather ugly on Usenet.

-- Richard
 
R

Richard Tobin

junk.c:6: warning: operation on 'i' may be undefined

In gcc 5, the -Wall warnings will be default warnings and the -Wextra
warnings will be promoted to -Wall.

That wouldn't be quite right. [snip]

You're (at least) the second person who's missed the part after the
control-L:[/QUOTE]

No, I was addressing the "dream". The mood of "wouldn't" was intended
to convey that.

-- Richard
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,434
Messages
2,571,691
Members
48,796
Latest member
Greg L.

Latest Threads

Top