What is difference b/w "UNSPECIFIED" and "UNDEFINED" behaviour ?

N

Nils Petter Vaskinn

Dan Pop wrote:
Your program is not required to be translated successfully, because of
the

*pint = *pint++;

statement.

So the mere existence of code that invokes undefined behavior causes
the entire program to be considered "undefined behavior", even if that
section of code isn't executed?

[...]

I think that's the implication yes.
But the actual behavior will very often happen to be as you would expect
up until the point you invoke undefined bahavior. (this is good). And some
times it will be as you expect for some time after you invoke undefined
behaviour. (this is bad).

The point is the standard doesn't say how it should behave, your compiler
may detect the undefined behaviour and refuse to compile your program.
Your compiler may make optimizations that assume everything is defined
behaviour, these optimizations may fail and resulting in errors _before_
the actual undefined code is reached. (I can't imagine how a compiler
would generate code to cause this, except for reordering statements for
optimization, which probably won't happen for 'dead code' that can't be
executed.) Or the compiler may very well have defined that behaviour and
all works well.

The point is that the standard doesn't mandate that _this_ particular form
of undefined bahaviour should cause _that_ particular thing, (then it
wouldn't be undefined would it?), if it did compiler makers would have
much less flexibility on how to make their product work.
 
K

Kenneth Brody

Nils said:
So the mere existence of code that invokes undefined behavior causes
the entire program to be considered "undefined behavior", even if that
section of code isn't executed?
[...]

I think that's the implication yes.
But the actual behavior will very often happen to be as you would expect
up until the point you invoke undefined bahavior. (this is good). And some
times it will be as you expect for some time after you invoke undefined
behaviour. (this is bad).

The point is the standard doesn't say how it should behave, your compiler [...]
The point is that the standard doesn't mandate that _this_ particular form
of undefined bahaviour should cause _that_ particular thing, (then it
wouldn't be undefined would it?), if it did compiler makers would have
much less flexibility on how to make their product work.

I realize that "undefined" means "anything is allowed here". I was just
wondering if it was the _existence_ or the _execution_ of the undefined-
behavior-invoking-code that caused the undefined behavior.

I realize that compiler writers are unlikely to do much more than either
generate some (semi-)valid code, issue a warning, or simply refuse to
compile the particular module. (And I'd be surprised if a compiler did
anything other than the fist choice.) They're not likely to generate code
to reformat the hard drive upon program startup. Nor are they likely to
have any undefined behavior occur prior to the actual execution of the
segment of code.

I was just curious if the standard said the code had to actually be
executed for "undefined behavior" to occur.

--

+---------+----------------------------------+-----------------------------+
| Kenneth | kenbrody at spamcop.net | "The opinions expressed |
| J. | http://www.hvcomputer.com | herein are not necessarily |
| Brody | http://www.fptech.com | those of fP Technologies." |
+---------+----------------------------------+-----------------------------+
 
E

Eric Sosman

Kenneth said:
I realize that "undefined" means "anything is allowed here". I was just
wondering if it was the _existence_ or the _execution_ of the undefined-
behavior-invoking-code that caused the undefined behavior.

Both kinds can occur. Examples:

int main(int argc, char **argv) {
return (argc > 1) ? *argv[argc] : 0;
}

This program exhibits U.B. only if invoked with more than one
command-line argument; if invoked with just one argument (the
"program name"), it does nothing wrong. Thus, the U.B. can
occur only at run time unless the implementation can predict
the future.

#define const 666
#include <stdio.h>
int main(void) {
puts ("Goodbye, cruel world!");
return 0;
}

This program exhibits U.B. of a kind that is likely to be
detected at compile time.

/* file1.c */
#include <stdio.h>
extern double trouble;
int main(void) {
printf ("%g\n", trouble);
return 0;
}

/* file2.c */
#include <stdio.h>
int trouble(void) {
return puts("Right here in River City");
}

Neither of these files is incorrect in and of itself, but
the attempt to link them into a single program produces U.B.
that may have its effect before the program is executed.
 
K

Keith Thompson

Kenneth Brody said:
I realize that compiler writers are unlikely to do much more than either
generate some (semi-)valid code, issue a warning, or simply refuse to
compile the particular module. (And I'd be surprised if a compiler did
anything other than the fist choice.) They're not likely to generate code
to reformat the hard drive upon program startup.
[...]

Not deliberately, but if the system includes code that's capable of
formatting the hard drive, a program that exhibits undefined behavior
could plausibly invoke it.
 
D

Dan Pop

In said:
Dan said:
In said:
If a program invokes undefined behavior, does it mean that the entire
program is "undefined behavior", even if that code is never executed?
Or is it only "undefined behavior" at the time the particular code is
executed (and from that point on)?

For example: [...]
Is this program guaranteed to at least print 0 through 8, or does
the undefined behavior in do_undefined() mean that the program can
do something "undefined" before i reaches 8?

Your program is not required to be translated successfully, because of
the

*pint = *pint++;

statement.

So the mere existence of code that invokes undefined behavior causes
the entire program to be considered "undefined behavior", even if that
section of code isn't executed?

Yes. If the compiler gets to compile this line, its behaviour is no
longer constrained by the C standard.

2 NOTE Possible undefined behavior ranges from ignoring the
situation completely with unpredictable results, to behaving
during translation or program execution in a documented manner
^^^^^^^^^^^
characteristic of the environment (with or without the issuance of
a diagnostic message), to terminating a translation or execution
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
(with the issuance of a diagnostic message).

As I have already explained, things are different for undefined behaviour
that cannot be decided at compile time, but this is not such a case.

Dan
 
D

Dave Thompson

(e-mail address removed) (Nitin Bhardwaj) wrote: (re C99 3.4.3 and 3.4.4)
So it boils down to the following :
UNDEFINED : The implementor can break into your house, the *Standard*
can't do anything about it;;Then why does the compiler allow such thing(s)
to get compiled in the first place ???

Because the compiler cannot detect all instances of undefined
behavior at compile time. Take the following example:

int foo(int *p)
{
return p[50];
}

How is the compiler to know wether or not this function invokes
undefined behavior?

It will invoke undefined behavior if p is NULL, or p is not a valid
pointer, or p is a valid pointer, but points to a block of memory that
is not large enough to hold 51 int's.
Not large enough or not correctly (sufficiently) aligned.

Or, technically, where that memory was last stored as another type
(possibly as bytes) creating a representation that is not a valid int
representation -- but there are few if any platforms that actually
have trap representations in integer types, though it is allowed
except for unsigned char.

Or, for completeness sake, the actual object is volatile, but that
qualifier was cast away at some intermediate point.
It will invoke unspecified behavior if p points to a block of memory
that is large enough, but for which the 51's element has not been
initialized or assigned a known value.

Use of an indeterminate (uninitialized) value is also Undefined
Behavior; besides the theoretical possibly of a trap represenation, it
would also be legal and possibly valuable (though costly without
special hardware, which is arguably costly in its own way) for an
implementation to detect and diagnose use of uninitialized memory.

The only Unspecifieds that I can see applying here are:

- p[50] is part of a member of a union when the last store was to a
different member (in practice, a differently typed one) but did not
create a trap representation -- maybe, this one is not crystal clear;
or was derived (without other UB like overflow) from one or more bytes
(or parts) of a representation that includes padding bytes, union
"residue" bytes, or padding bits in a type that allows and uses them;
or multiple representations, or negative zero, if used.

- or for that matter, on the vanishingly few machines that have
(integer) negative zero some (specified) operations may unspecifiedly
produce it instead of positive; but *used as an int value* it gives
the same results as positive, and so mostly doesn't matter.

- p[50] was affected by order of side effects in initialization of an
aggregate variable or compound literal, or of subexpression (operand)
or function argument evaluation; in particular if
int bar (int *p) { return p[50] = 42; }
int quux (int a, int b) { return a; }
.... int x[51] = {0}; ... quux (foo(p), bar(p)) ...
unspecifiedly produces 0 or 42 -- at least (I think) in C90 with
DR087, though not AFAICS explicitly reflected in C99, except probably
in the attempted "formal model" stuff that didn't make it. (And note
this depends on the sequence points on the calls to foo and bar; if
those were just expressions, or macros, you're back to Undefined.)

- p[50] contains a value produced by certain library functions such as
ftell() or time(), converted down if needed; but these are almost
certainly documented even though not mandated by the standard.

- David.Thompson1 at worldnet.att.net
 

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

Forum statistics

Threads
473,764
Messages
2,569,564
Members
45,040
Latest member
papereejit

Latest Threads

Top