Increment operator

A

Army1987

Keith Thompson said:


3

Why, what were you expecting? :)
(Not sure on whether the temporary plonk has expired, but:)
#include <stdio.h>
int main(void)
{
int i = 3;
if (getchar() = 'y')
i = i++;
printf("%d\n", i);
return 0;
}
What does it do if you input y? What does it do if you input n?

#include <stdio.h>
size_t counter(void)
{
static size_t count = 0;
return count++;
}
#define i a[counter()]
int main(void)
{
int a[2] = {23, 47};
i = i++;
printf("%d %d\n", a[0], a[1]);
return 0;
}
What does it do? It is allowed to print "24 23" or to print
"47 48", but not anything else. (The order of function calls is
unspecified, but they can't overlap, so the increment to count the
second time the function is called has to happen after the
sequence point due to the end of the return statement in the first
time.) And:
#include <stdio.h>
{
int a[2] = {0, 3};
int answer = (getchar() == 'y');
a[answer] = a[1]++;
printf("%d\n", a[1]);
return 0;
}
This must print 4 if I don't input y, but is allowed to do
anything if I do. <ot>But if it happened to do anything else than
printing 3 or printing 4, I would be extremely astonished and
curious about how the implementation works.</ot>
 
J

Jean-Marc Bourguet

Army1987 said:
#include <stdio.h>
{
int a[2] = {0, 3};
int answer = (getchar() == 'y');
a[answer] = a[1]++;
printf("%d\n", a[1]);
return 0;
}
This must print 4 if I don't input y, but is allowed to do
anything if I do. <ot>But if it happened to do anything else than
printing 3 or printing 4, I would be extremely astonished and
curious about how the implementation works.</ot>

I can give a plausible explanation for 511 and 0 values if the 3 is
replaced by 255.

8 bits byte. 16 bits int. Only byte access at the machine level. The two
writes are interleaved.

And obviously when optimisers comes into play... they can makes a program
like

if (i == INT_MAX) {
puts("1");
} else {
puts("2");
}
++i;

print "2" when i == INT_MAX (reason: for the ++i to be valid, i should
never be INT_MAX, so the test is always false and optimised away; gcc does
such kind of analysis but I don't know if they go as far as that in
exploiting the notion of UB so that it seems to have non causal effect).

Yours,
 
C

CBFalconer

Army1987 said:
.... snip ...

#include <stdio.h>
size_t counter(void) {
static size_t count = 0;
return count++;
}
#define i a[counter()]
int main(void) {
int a[2] = {23, 47};
i = i++;
printf("%d %d\n", a[0], a[1]);
return 0;
}
What does it do? It is allowed to print "24 23" or to print
"47 48", but not anything else. (The order of function calls is
unspecified, but they can't overlap, so the increment to count
the second time the function is called has to happen after the
sequence point due to the end of the return statement in the
first time.) And:

Nonsense. The "i = i++;" statement exhibits undefined behaviour,
and has been executed. The program can do anything at all.
 
K

Kelsey Bjarnason

By definition, people who miss the point are not able to understand the
point that they have missed. Therefore, I shan't bother explaining it
to you.

I see. There is no expectation of any result, you assert there is, you
cannot give any reason for this assertion, yet the problem is somehow
mine, not yours.

Sorry, but when reality says one thing and you say another, I'll go with
reality.

Keith T is right; you're a troll, and not a very bright one at that. Ta
ta.
 
K

Kelsey Bjarnason

Thanks for clearing that up, I still wasn't 100% sure
that what I wrote was correct. I guess the relevant
line of that page is the last one:
"Because foo might never be called, the example given
must be successfully translated by a conforming implementation."

Note that, as I read it, this is from a footnote, hence not normative.
 
K

Keith Thompson

Richard Heathfield said:
CBFalconer said:

Not if it's never executed, it doesn't. Read main() again.

And if you (generic "you") think that a statement that would exhibit
UB if it were executed, but can never actually be executed, should be
allowed to exhibit UB anyway, consider this:

#include <stdio.h>
#include <limits.h>
int main(void)
{
int n = 32767;
if (INT_MAX > 32767) {
n ++;
}
printf("n = %d\n", n);
return 0;
}

Should a compiler on a system with 16-bit int be allowed to reject or
otherwise mangle this program? I think not. But if INT_MAX is 32767,
the statement 'n ++;' would invoke undefined behavior *if* it were
executed. The program must print either "n = 32767" or "n = 32768";
any other behavior is non-conforming.
 
P

pete

Keith said:
And if you (generic "you") think that a statement that would exhibit
UB if it were executed, but can never actually be executed, should be
allowed to exhibit UB anyway,

Here's a Douglas A. Gwyn comment on that matter:
http://groups.google.com/group/comp.lang.c/msg/eea52eda7d7679f4



consider this:

#include <stdio.h>
#include <limits.h>
int main(void)
{
int n = 32767;
if (INT_MAX > 32767) {
n ++;
}
printf("n = %d\n", n);
return 0;
}

Should a compiler on a system with 16-bit int be allowed to reject or
otherwise mangle this program? I think not. But if INT_MAX is 32767,
the statement 'n ++;' would invoke undefined behavior *if* it were
executed. The program must print either "n = 32767" or "n = 32768";
any other behavior is non-conforming.

I don't see that program as being close to being undefined.
 
K

Keith Thompson

pete said:
Keith Thompson wrote: [...]
consider this:

#include <stdio.h>
#include <limits.h>
int main(void)
{
int n = 32767;
if (INT_MAX > 32767) {
n ++;
}
printf("n = %d\n", n);
return 0;
}

Should a compiler on a system with 16-bit int be allowed to reject or
otherwise mangle this program? I think not. But if INT_MAX is 32767,
the statement 'n ++;' would invoke undefined behavior *if* it were
executed. The program must print either "n = 32767" or "n = 32768";
any other behavior is non-conforming.

I don't see that program as being close to being undefined.

I see it as being *close* to undefined, but in such a way that it
never actually *is* undefined. It's admittedly a subtle distinction.

I can imagine a compiler being simultaneously clever and stupid enough
to reject the program because it thinks 'n ++;' must invoke undefined
behavior. Such a compiler would be non-conforming, of course, and
such behavior is merely a nearly plausible compiler bug.
 
K

Keith Thompson

CBFalconer said:
Army1987 said:
... snip ...

#include <stdio.h>
size_t counter(void) {
static size_t count = 0;
return count++;
}
#define i a[counter()]
int main(void) {
int a[2] = {23, 47};
i = i++;
printf("%d %d\n", a[0], a[1]);
return 0;
}
What does it do? It is allowed to print "24 23" or to print
"47 48", but not anything else. (The order of function calls is
unspecified, but they can't overlap, so the increment to count
the second time the function is called has to happen after the
sequence point due to the end of the return statement in the
first time.) And:

Nonsense. The "i = i++;" statement exhibits undefined behaviour,
and has been executed. The program can do anything at all.

Look more closely. 'i' is defined as a macro involving a function
call. The statement 'i = i++;' does not, in this case, modify the
stored value of any object twice between the previous and next
sequence point; the two 'i's refer to two different objects. The
order is unspecified, but I don't believe there's any undefined
behavior.

It's horribly bad code, of course, but it's not intended to be decent
code; it's intended to break a hypothetical conforming implementation
that prints "a suffusion of yellow" in response to the undefined
behavior of 'i = i++;'.

(One of the ways I've thought of to implement the hypothetical
implementation would not be vulnerable to this method.)
 

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,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top