operation on `x' may be undefined?

J

jimjim

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"?

TIA
 
D

David Resnick

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"?

TIA

Nice compiler warning! Anyway, see the FAQ:

http://www.eskimo.com/~scs/C-faq/q3.2.html

-David
 
A

Antonio Contreras

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"?

TIA

Why don't you read the FAQ before posting something that has been asked
and answered thounsands of times before?
 
C

Chris Dollin

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"?

(a) Read the FAQ.

(b) Given the compiler warning, why are you surprised at the output?
 
J

John Bode

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"?

TIA

You're running into two issues:

1. Undefined behavior -- you are attempting to modify the value of an
object more than once between sequence points, and the Standard imposes
no requirement on how to handle that behavior. Basically, any
expression of the forms:

i = i++;
j = k++ * k++;
foo(i,i++,--i);

invoke undefined behavior. Read up on the semantics of the "++" and
"--" operators in an *authoritative* reference (the Standard would
obviously be one, but also K&R2 or H&S5); they don't work the way most
people think they should.

2. Order of evaluation -- AFAIK, there's no requirement that
expressions in a function parameter list be evaluated in any particular
order. At first blush, it *looks* like the arguments were evaluated
from right to left (if x = 1, then x++ evaluates to 1, with the side
effect that x == 2, and ++x evaluates to 3, with the side effect that x
== 3), but given that you've invoked undefined behavior the actual
reason may be something else entirely.
 
L

Lew Pitcher

-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1
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"?

Because the order of evaluation of function arguments is not defined by
the standard, and, in the evaluation of the arguments to your printf()
function call, the value of x at any one point depends on the value of x
at some other point
Why when run the output is: "3 2 1"?

Because, with "undefined operations", /any/ result is a valid result.


- --

Lew Pitcher, IT Specialist, Enterprise Data Systems
Enterprise Technology Solutions, TD Bank Financial Group

(Opinions expressed here are my own, not my employer's)
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.2.4 (MingW32)

iD8DBQFC+im3agVFX4UWr64RAlp4AKCPdVuxVcwMuLj8c2ARKNyfhC8ZkgCeK21z
X9885DRA8ph6o5JhLCo0QEI=
=277u
-----END PGP SIGNATURE-----
 
A

akarl

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"?

It all comes down to the concept of *sequence points*. In an expression
that contains no sequence points an object may not be modified and
accessed in different subexpressions (since the side effects of the
subexpressions may take place in any order).

See http://publications.gbdirect.co.uk/c_book/chapter8/sequence_points.html


August
 
J

jimjim

(b) Given the compiler warning, why are you surprised at the output?Given that my compiler is the gcc, could you have a guess why is it 3 2 1
and not 1 2 3? ;-)
 
J

jimjim

Given that my compiler is the gcc, could you have a guess why is it 3 2 1
and not 1 2 3? ;-)
I am happy that others in this group are happy to provide **answers** and
not just waffling
 
K

Keith Thompson

jimjim said:
Given that my compiler is the gcc, could you have a guess why is it 3 2 1
and not 1 2 3? ;-)

If I were more familiar with the details of gcc's code generation, I
might, but such a guess would not be useful. The code invokes
undefined behavior, which means it could behave differently with the
next release of gcc or with the phase of the moon.

The code is broken. The only appropriate thing to do is fix it.
 
J

Joe Wright

jimjim said:
I am happy that others in this group are happy to provide **answers** and
not just waffling
Ignorance is bliss I suppose. I can't tell what you are referring to as
waffling.

printf("%d %d %d\n", ++x, x, x++);

I'll guess that someone told you that treating x this way is stupid and
that you should read a C book or at least the FAQ.

If you are unwilling to do that and want me to look it up and quote it
to you, you've got the wrong guy.
 
K

kernelxu

John has given a guess:
2. Order of evaluation -- AFAIK, there's no requirement that
expressions in a function parameter list be evaluated in any particular
order. At first blush, it *looks* like the arguments were evaluated
from right to left (if x = 1, then x++ evaluates to 1, with the side
effect that x == 2, and ++x evaluates to 3, with the side effect that x
== 3), but given that you've invoked undefined behavior the actual
reason may be something else entirely.

I think this is caused by the Function Calling Conventions used by your
complier.
maybe you compiler set a prefix "_cdecl" for every standard function.
(you could find that by opening a header file).
there are some rules about _cdecl, more about it, there is a webpage:
http://www.programmers-corner.com/tutorial/16

_cdecl
Arguments Passed from Right to Left
Calling Function Clears the Stack
‘this’ pointer is passed via stack last in case of Programs
using OOP
Functions using _cdecl are preceded by an “_”

so, the first "Arguments Passed from Right to Left " one is the key to
your problem.
 
J

Jack Klein

John has given a guess:

I think this is caused by the Function Calling Conventions used by your
complier.

You are wrong to think that.
maybe you compiler set a prefix "_cdecl" for every standard function.
(you could find that by opening a header file).
there are some rules about _cdecl, more about it, there is a webpage:
http://www.programmers-corner.com/tutorial/16

Why do you think a web page that says it specifically and only refers
to one version of one compiler has anything to do with the language
standard, or even any other compiler?

The code is broken because it does something that the C standard says
it undefined behavior, a very specific term. Whatever the program
actually does is irrelevant and off-topic here. The C language does
not know or care, and anything the program does is just as right or
just as wrong as anything else.
 
K

Keith Thompson

Jack Klein said:
The code is broken because it does something that the C standard says
it undefined behavior, a very specific term. Whatever the program
actually does is irrelevant and off-topic here. The C language does
not know or care, and anything the program does is just as right or
just as wrong as anything else.

On the other hand, it can sometimes be useful to know what a
particular compiler is likely to do when confronted with undefined
behavior. Sometimes fixing the code isn't an option, or requires a
tremendous amount of effort; for example, if the code has already been
deployed, and is generally working correctly, the risk of making a
change may exceed the benefit of fixing a possible bug. There may be
other code that incorrectly depends on a the way a particular instance
of undefined behavior is handled; fixing one but not the other can
break a working program, even if it works only by accident.

Also, if I see "void main()", for example, I'm going to want to
correct it, but knowing that most compilers don't actually screw
things up too badly in the presence of "void main()" might tell me
that I need to keep looking elsewhere for the cause of the mysterious
bug I'm seeing.

For the purpose of writing new code, all you really need to know is
that undefined behavior is to be avoided. For the purpose of
understanding the behavior of existing code, knowing some of the
undefined and implementation-specific details can be useful -- as long
as you're aware that the details are undefined and
implementation-specific.

I don't believe that the original poster's situation was one that
calls for this kind of knowledge, though.
 
J

jimjim

If I were more familiar with the details of gcc's code generation, I
might, but such a guess would not be useful. The code invokes
undefined behavior, which means it could behave differently with the
next release of gcc or with the phase of the moon.

Hi there..thx for the reply

Is the footnote 70 of 6.5.2 that talks about
 
J

jimjim

If I were more familiar with the details of gcc's code generation, I
might, but such a guess would not be useful. The code invokes
undefined behavior, which means it could behave differently with the
next release of gcc or with the phase of the moon.

Hi there..thx for the reply

Is the footnote 70 of 6.5.2 that talks about undefined behavior?

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, and then the i++ would have been performed before
proceeding to the next statement in the code.

TIA

P.S: posters should stop making assumptions that newbies can comprenhend
everything they are reading in the FAQ!
 
C

Chris Dollin

jimjim said:
I am happy that others in this group are happy to provide **answers** and
not just waffling

If you're referring to /me/, I provided an answer; I told you to read
the FAQ, which has a clear and detailed discussion on this topic.
 
J

jimjim

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?
2. Is there a possibility for an implementation to choose some behavior for
a Standard-specified Undefined behaviour and document it?

as always TIA
 

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,777
Messages
2,569,604
Members
45,234
Latest member
SkyeWeems

Latest Threads

Top