operation on `x' may be undefined?

C

Chris Dollin

jimjim said:
70) This paragraph renders undefined statement expressions such as
i = ++i + 1;

a[i++] = i;

why does the last expression invoke undefined behavior? The value of i is
changed once (I would have guessed that the initial value of i would have
been stored in a,

Why not the final value?
and then the i++ would have been performed before
proceeding to the next statement in the code.

The standard says (I paraphrase, correctly I hope) that an object
can be updated at most once between sequence points, and an updated
objects "previous" value can be read only to compute the value to be
stored.

In `a[i++] = i`, `i` is updated, and its value is read (on the RHS)
for a reason other than to determine its new value. BOOM.
P.S: posters should stop making assumptions that newbies can comprenhend
everything they are reading in the FAQ!

I'm not making that assumption. /Asking/ (sensible) questions about
the FAQ entries is fine. Not bothering to read them wouldn't be.
 
J

jimjim

and an updated objects "previous" value can be read only to compute the
In order to make sure that I understand what you are saying, is the sentence
below equivalent with yours?
If between sequence points an object's value is to be modified , its value
should only be read once.


TIA
 
A

Antonio Contreras

jimjim said:
In order to make sure that I understand what you are saying, is the sentence
below equivalent with yours?
If between sequence points an object's value is to be modified , its value
should only be read once.

No. For example:

int i = 5;

i = i * i;

is perfectly legal, and the value of i is accessed twice (the compiler
might optimize accesses and remember the value without having to read
it both times, but this is not the point).

The standard says what ir says. If an object is to be modified between
two sequence points, then it can only be written once, and read
accesses must be done in order to compute the new value, and for no
other porpouse.

Now, answering your original question.

a = i++;

This statement invokes undefined behaviour because the value of i is
being accessed for some other porpouse than to compute its new value.

The reason why this is specified to be undefined behaviour is that
specifying certain behaviour would impose lots of constraints on
compiler design without any measurable improvement.

Consider you're designing a compiler and have to decide what to do when
faced with the above expression. There are 3 main tasks you should
consider:

1. Get the value of i.
2. Increment i.
3. Compute the address to which the value must be written
(&a + i * sizeof(a[0]))

This things can be done in whatever order the compiler designers decide
suits best their target architecture. If you perform the operation in
the order in which I've written them, the result would be the same that
if you had written:

a[i + 1] = i;
i++;

(Because i has already been incremented when the compiler computes the
address to wich the data must be written.)

But this is not the only possible way. If you compute the address
first, then the value to be stored, the result would be that of:

a = i;
i++;

Which is probably what was intended in first place.

HTH
 
J

jimjim

The standard says what ir says. If an object is to be modified between
two sequence points, then it can only be written once, and read
accesses must be done in order to compute the new value, and for no
other porpouse.
This now makes sense to me. thx
 
K

Keith Thompson

jimjim said:
Hi there..thx for the reply
[snip]

Please provide attributions. I see you're using Microsoft Outlook
Express, which I'm fairly sure should do this for you. The text
prefixed by ">> " was mine, so it should be preceded by something like


It's easier to follow the discussion when we can see who wrote what.
 
K

Keith Thompson

jimjim said:
Moreover, http://www.eskimo.com/~scs/C-faq/q11.33.html refers to
implementation-defined.
1. Is implementation-defined stated in particular sections of the Standard?

Yes. The term "implementation-defined behavior" is defined in C99 3.4.1 as

unspecified behavior where each implementation documents how the
choice is made

If you search for "implementation-defined" in the standard, you'll
find many examples.
2. Is there a possibility for an implementation to choose some behavior for
a Standard-specified Undefined behaviour and document it?

Sure, an implementation can define anything it likes. You should be
careful about depending on such things, though, since they likely
won't work the same way on other implementations.
 
F

Flash Gordon

jimjim said:
Moreover, http://www.eskimo.com/~scs/C-faq/q11.33.html refers to
implementation-defined.
1. Is implementation-defined stated in particular sections of the Standard?

As I understand it, implementation defined means that the implementation
is *required* to both define and document the behaviour.
2. Is there a possibility for an implementation to choose some behavior for
a Standard-specified Undefined behaviour and document it?

An implementation can do whatever it wants with undefined behaviour
*including* document what it does (the standard even says it is allowed
to document it). Indeed, this is a "standard" way of extending C.

To quote from the standard:

| 3.4.1
| 1 implementation-defined behavior
| unspecified behavior where each implementation documents how the choice
| is made
| 2 EXAMPLE An example of implementation-defined behavior is the propagation
| of the high-order bit when a signed integer is shifted right.


| 3.4.3
| 1 undefined behavior
| behavior, upon use of a nonportable or erroneous program construct or of
| erroneous data, for which this International Standard imposes no
| requirements
| 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).
| 3 EXAMPLE An example of undefined behavior is the behavior on integer
overflow.
|
| 3.4.4
| 1 unspecified behavior
| use of an unspecified value, or other behavior where this International
| Standard provides two or more possibilities and imposes no further
| requirements on which is chosen in any instance
| 2 EXAMPLE An example of unspecified behavior is the order in which the
| arguments to a function are evaluated.
 
M

Mark

jimjim said:
Hello,

#include <stdio.h>

int main(int argc, char *argv[])
{
int x = 1;
printf("%d %d %d\n", ++x, x, x++);
return 0;
}

Why does the above code when compiled with all warnings it issues: "
warning: operation on `x' may be undefined"?
Why when run the output is: "3 2 1"?

Everyone here is quick to post that the code invokes undefined behavior,
but doesn't the following excerpt from the standard explicitly allow it?

7.19.6 Formatted input/output functions
1) The formatted input/output functions shall behave as if there is a
sequence point after
the actions associated with each specifier.
7.19.6.1 The fprintf function

Mark
 
K

Keith Thompson

Mark said:
jimjim said:
Hello,

#include <stdio.h>

int main(int argc, char *argv[])
{
int x = 1;
printf("%d %d %d\n", ++x, x, x++);
return 0;
}

Why does the above code when compiled with all warnings it issues: "
warning: operation on `x' may be undefined"?
Why when run the output is: "3 2 1"?

Everyone here is quick to post that the code invokes undefined behavior,
but doesn't the following excerpt from the standard explicitly allow it?

7.19.6 Formatted input/output functions
1) The formatted input/output functions shall behave as if there is a
sequence point after
the actions associated with each specifier.
7.19.6.1 The fprintf function

No, I don't think so. The evaluation of the arguments occurs before
the function is called, and is not part of "the actions associated
with each specifier". The quoted statement contrains the internal
behavior of the functions themselves. It implies that the following
(rather silly) code fragment does not invoke undefined behavior:

int count;
printf("hello%n, world%n\n", &count, &count);

(I'm sure there are non-silly examples, but I can't think of any off
the top of my head.)
 
R

Robert Gamble

Mark said:
jimjim said:
Hello,

#include <stdio.h>

int main(int argc, char *argv[])
{
int x = 1;
printf("%d %d %d\n", ++x, x, x++);
return 0;
}

Why does the above code when compiled with all warnings it issues: "
warning: operation on `x' may be undefined"?
Why when run the output is: "3 2 1"?

Everyone here is quick to post that the code invokes undefined behavior,
but doesn't the following excerpt from the standard explicitly allow it?

7.19.6 Formatted input/output functions
1) The formatted input/output functions shall behave as if there is a
sequence point after
the actions associated with each specifier.
7.19.6.1 The fprintf function

No. You seem to be reading "actions associated with each specifier" as
"evaluation of each parameter", it means what it says, really. This
keeps things like the following from invoking undefined behavior:

int i;
scanf("%d %d", &i, &i);

If not for that clause, i could be modified twice without an
intervening sequence point. Examples of how this could happen are
probably quite contrived but that is the purpose behind the clause. As
for the fprintf functions, the %n conversion specifier performs writes
to memory as pointed out by the footnote to the clause you quoted.

Robert Gamble
 

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
473,768
Messages
2,569,574
Members
45,051
Latest member
CarleyMcCr

Latest Threads

Top