Doubt in Question From C Faq

S

Sandeep

http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?
 
K

Kelsey Bjarnason

[snips]

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


It *doesn't* work on some implementations. The problem is, it invokes
undefined behaviour, so any result is acceptable - including seeming to
work.

Because *any* result is acceptable, though, you have no real expectation
it will continue to work, or work with a different compiler, different
optimization settings, etc; if it does, it is simply "by luck".
 
P

pemo

Sandeep said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


a = i++;

It's a good question, i.e., I can see your point I think -> Isn't it the
case that post-increment is always the last thing done - whereas
pre-increment is alwats the first thing done? In that case, surely the
valie of i is consistently the same on both sides of the assignment
operator?
6.5 2 of the std says

Between the previous and next sequence point an object shall have its stored
value modified at most once by the evaluation of an expression. Furthermore,
the prior value shall be read only to determine the value to be stored.70)

The '70' refers to:

70) This paragraph renders undefined statement expressions such as

i = ++i + 1;

a[i++] = i;

while allowing

i = i + 1;

a = i;
 
K

Keith Thompson

Sandeep said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.


Try the full version of the FAQ at
<http://www.eskimo.com/~scs/C-faq/top.html>.

Question 3.1

Why doesn't this code:

a = i++;
work?

The subexpression i++ causes a side effect--it modifies i's
value--which leads to undefined behavior since i is also
referenced elsewhere in the same expression. (Note that although
the language in K&R suggests that the behavior of this expression
is unspecified, the C Standard makes the stronger statement that
it is undefined--see question 11.33.)

The code invokes undefined behavior. As far as the standard is
concerned, it can "work" (whatever that means), or it can make demons
fly out of your nose.
 
G

gary

http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


see:
11.35: People keep saying that the behavior of i = i++ is undefined,
but I just tried it on an ANSI-conforming compiler, and got the
results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior (and, within limits, with implementation-defined and
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.
 
S

Sandeep

pemo said:
a = i++;
Isn't it the
case that post-increment is always the last thing done - whereas
pre-increment is alwats the first thing done? In that case, surely the
valie of i is consistently the same on both sides of the assignment
operator?

This is what confused me.

a = ++i; // Logical to say that "i" has changed before the
expression could end
a = i++; // This seemed ok to me.
Is the copy of C Std available on internet ? If yes, can you please
post the link to me.

If it is defined in the standard, I can pretty much do nothing about it
:) . But do you think there is a reason for having this undefined
behaviour? Is the reason to be consistent with the pre-increment
operator ?
 
S

slebetman

gary said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


see:
11.35: People keep saying that the behavior of i = i++ is undefined,
but I just tried it on an ANSI-conforming compiler, and got the
results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior (and, within limits, with implementation-defined and
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.


Well..

the result:
1,1,3,4,5,6 was what he got but
2,2,3,4,5,6 would also be correct and
1,2,3,4,5,6 is correct as well.

That's why it doesn't work. You don't really know what the code does.
Different compilers may produce different results. Also, the same
compiler on different architectures can also produce different results
depending on the assembly generated.
 
S

slebetman

gary said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


see:
11.35: People keep saying that the behavior of i = i++ is undefined,
but I just tried it on an ANSI-conforming compiler, and got the
results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior (and, within limits, with implementation-defined and
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.


Well..

the result:
1,1,3,4,5,6 was what he got but
2,2,3,4,5,6 would also be correct and
1,2,3,4,5,6 is correct as well.

That's why it doesn't work. You don't really know what the code does.
Different compilers may produce different results. Also, the same
compiler on different architectures can also produce different results
depending on the assembly generated.


oops sorry, 2,2,3,4,5,6 is impossible but 1,2,3,4,5,6 is still a
possible result.
 
I

Ian Malone

Sandeep said:

This is what confused me.

a = ++i; // Logical to say that "i" has changed before the
expression could end
a = i++; // This seemed ok to me.


If it is defined in the standard, I can pretty much do nothing about it
:) . But do you think there is a reason for having this undefined
behaviour? Is the reason to be consistent with the pre-increment
operator ?

My impression, and I could be wrong, is that it's a nod to writers of
compilers and optimisers who may be able to use various tricks if they
can assume people aren't going to do this. (The fact that is does
apparently behave differently on some platforms tells you that a few
cats have been skinned in differing ways.)
 
P

pete

gary said:
On 8 Nov 2005 00:48:49 -0800

http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me !
Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?

see:
11.35: People keep saying that the
behavior of i = i++ is undefined,
but I just tried it on an ANSI-conforming compiler,
and got the
results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior (and, within limits, with implementation-defined and
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.


Well..

the result:
1,1,3,4,5,6 was what he got but
2,2,3,4,5,6 would also be correct and
1,2,3,4,5,6 is correct as well.

oops sorry, 2,2,3,4,5,6 is impossible but 1,2,3,4,5,6 is still a
possible result.

All results are possible with undefined code.
(a = i++) is such bad and pointless code,
that the authors of the C standard just simply don't care
what happens when you write code like that.
When it's finally translated on the abstract machine,
it means nothing.
 
P

pete

pemo said:
Isn't it the case that post-increment is always the last thing done

No.
(x++) is an expression that has a value and a side effect.
The side effect is that x is incremented.
The value of the expression is the value that it had
before it was incremented, but the determination of the value
can be done either before or after the increment.
Things that happen between sequence points,
have no specified order.
A statement terminating semicolon is an example of a sequence point.

For integer types of x,
(x++ == 5) means exactly the same thing as (++x == 6)
on the abstract machine.
 
F

Flash Gordon

Sandeep said:
pemo said:
a = i++;
Isn't it the
case that post-increment is always the last thing done - whereas
pre-increment is alwats the first thing done? In that case, surely the
valie of i is consistently the same on both sides of the assignment
operator?

This is what confused me.

a = ++i; // Logical to say that "i" has changed before the
expression could end
a = i++; // This seemed ok to me.


Post increment does *not* mean that i is incremented last (or even after
the value is returned), it only means that the value "returned" is what
the value was before the increment. So the compiler could implement the
above as
increment i
find address of a
assign the old value of i to a
Is the copy of C Std available on internet ? If yes, can you please
post the link to me.

You can get a draft C99 updated with TC1 from
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1124.pdf
Note, however, that most implementations do not fully conform to C99
yet, although they can be made to conform to the older C89/C90 standard.
If it is defined in the standard, I can pretty much do nothing about it
:) . But do you think there is a reason for having this undefined
behaviour? Is the reason to be consistent with the pre-increment
operator ?

It is probably mainly to do with allowing optimisers to do clever things
and allowing for efficient implementations.

You may find information in the rationale which you can get from
http://www.open-std.org/jtc1/sc22/wg14/
 
P

pemo

Sandeep said:
Is the copy of C Std available on internet ? If yes, can you please
post the link to me.

I spent $18 getting a copy off the ANSI site - it's well worth it!
 
C

Clark S. Cox III

gary said:
On 8 Nov 2005 00:48:49 -0800

http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?

see:
11.35: People keep saying that the behavior of i = i++ is undefined,
but I just tried it on an ANSI-conforming compiler, and got the
results I expected.

A: A compiler may do anything it likes when faced with undefined
behavior (and, within limits, with implementation-defined and
unspecified behavior), including doing what you expect. It's
unwise to depend on it, though. See also questions 11.32,
11.33, and 11.34.


Well..

the result:
1,1,3,4,5,6 was what he got but
2,2,3,4,5,6 would also be correct and
1,2,3,4,5,6 is correct as well.

That's why it doesn't work. You don't really know what the code does.
Different compilers may produce different results. Also, the same
compiler on different architectures can also produce different results
depending on the assembly generated.


oops sorry, 2,2,3,4,5,6 is impossible but 1,2,3,4,5,6 is still a
possible result.


No, there are no impossible results, the code could produce:

123,5245243,653,2134,2357,346,12357

for all the standard cares
 
K

Kenny McCormack

oops sorry, 2,2,3,4,5,6 is impossible but 1,2,3,4,5,6 is still a
possible result.

No, there are no impossible results, the code could produce:

123,5245243,653,2134,2357,346,12357

for all the standard cares[/QUOTE]

I think that should be our standard response to most off-topic/UB-invoking
posts. Just say:

Well, I just tried it on my system and the result was:
123,5245243,653,2134,2357,346,12357
 
R

Randy Howard

Sandeep wrote
(in article
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.


It works fine for me ! Maybe I have not understood the question "Why
doesn't the code "a = i++;" work?" . Any ideas ?


One of the hardest things to get used to for the newcomer to
programming, is that just because "it works for me" does not
make it proper anywhere else. If you really want to know all
the details (warning: hundreds or thousands of hours will
disappear from your life if you do), then sit down and read the
ISO C standards documents front to back.

Or, you could trust that the clc FAQ has been vetted pretty well
over the years.
 
C

Chris Torek

http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.


As everyone else has noted, this is the "short version" FAQ; the
long version has more explanation.

[some vertical-space adjustment below]
Here is the code that I have written:
#include <stdio.h>

int main () {
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Output (using gcc (GCC) 3.4.2 (mingw-special))

1 1 3 4 5 6

It works fine for me !


What makes you say that? Should the output not have been "1 2 1
4 5 6"?

Consider: i++ means "evaluate i and schedule an increment", and i
was 1 so the value is 1 and i becomes 2. Then a = <expr> means
"evaluate i and set a", and i is now 2, so a[2] should have been
set to 1.

Why is my interpretation here of what "should" happen any less (or
perhaps more) reasonable than your interpretation of what "should"
happen?

Of course, the fact is that Standard C says the effect is undefined,
so no matter what happens, your C implementation cannot be called
"wrong". In this case, there are multiple "reasonable" interpretations,
and the ISO C standard allows any of them -- so no matter which
one *you* prefer, your compiler can choose some other one, and do
something that you did not intend. The only solution available to
the C programmer is to avoid the situation in the first place:
write code that has only *one* allowed interpretation, and you will
get that one interpretation.
 
M

Mark B

Sandeep said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me !

WHAT??? Take another look at your results...
HINT: where is the number 2???
 
S

Skarmander

Mark said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me !


WHAT??? Take another look at your results...
HINT: where is the number 2???

I ate it.

Reread the program, then look for a brown paper bag to pull over your
head. HINT: what does assignment do?

Optionally read the rest of the thread for completeness.

S.
 
P

pete

Skarmander said:
Mark said:
http://www.faqs.org/faqs/C-faq/abridged/
3.1: Why doesn't the code "a = i++;" work?

A: The variable i is both referenced and modified in the same
expression.

Here is the code that I have written:
#include <stdio.h>

int main ()
{
int a[] = {1,2,3,4,5,6};
int i=1;
int j;

a = i++;
for(j=0;j<6;j++)
printf("%d\n",a[j]);
}

Outout (using gcc (GCC) 3.4.2 (mingw-special))

1
1
3
4
5
6

It works fine for me !


WHAT??? Take another look at your results...
HINT: where is the number 2???

I ate it.

Reread the program, then look for a brown paper bag to pull over your
head. HINT: what does assignment do?


Exactly.
Is assignment, a sequence point?
No!
Is an expression defined when it modifies
and accesses an object without an intervening sequence point?
No!
Is a = i++; C code?
No,
it's just gibberish that looks like C code.
 

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,764
Messages
2,569,564
Members
45,039
Latest member
CasimiraVa

Latest Threads

Top