Implementation-defined behaviour

R

Richard Tobin

Ioannis Vranos said:
K&R2 mentions the following:

"printf("%d %d\n", ++n, power(2,n)); /* WRONG */

can produce different results with different compilers, depending on
whether n is incremented before power is called".


That's why I call it implementation-defined behaviour.

It's undefined behaviour, and therefore implementation dependent, but
"implementation defined" means that the implementation specifies (in
its documentation) what it does. The standard contains a list of the
behaviours that the implementation must specify, but this isn't one of
them.

-- Richard
 
E

Eric Sosman

Ioannis said:
Eric said:
Ioannis said:
AFAIK the following is implementation-defined behaviour, am I right?:
[...]
What aspect do you believe is not Standard-defined?
I am talking about the implementation-defined behaviour of the printf()
call described at 2.12 of K&R2.

Aha! This problem is explained on pages 366-7 of the
Frobozz Magic C version 42 Release Notes and Do-It-Yourself
Lobotomy Manual. Read it, and get back to me if there's
anything that's still unclear.
 
R

Richard Tobin

Eric Sosman said:
Aha! This problem is explained on pages 366-7 of the
Frobozz Magic C version 42 Release Notes and Do-It-Yourself
Lobotomy Manual.

I have a copy of the Encyclopedia Frobozzica on my bookshelf next to
K&R 2, but I've never seen the manual you mention. Is it still
available?

-- Richard
 
A

Antoninus Twink

So, printf("%d "%d\n", x++, x++); invokes implementation-defined
behaviour, while printf("%d\n", x++); doesn't invoke
implementation-defined behaviour?

Wonderful post! This is exactly what clc is for - another thrilling
discussion of i=i++. Hold onto your seats, folks - it's going to be an
exciting ride.
 
A

Antoninus Twink

K&R2 mentions the following:

"printf("%d %d\n", ++n, power(2,n)); /* WRONG */

can produce different results with different compilers, depending on
whether n is incremented before power is called".


That's why I call it implementation-defined behaviour.

Don't stop now! The regulars will be wetting themselves at the chance to
rehash so many FAQ answers!
 
J

jacob navia

Antoninus said:
Wonderful post! This is exactly what clc is for - another thrilling
discussion of i=i++. Hold onto your seats, folks - it's going to be an
exciting ride.

Yes, there we go

This is the *main* topic of this group:

n=n++;

Exciting. That is the word!

:)
 
E

Eric Sosman

Richard said:
I have a copy of the Encyclopedia Frobozzica on my bookshelf next to
K&R 2, but I've never seen the manual you mention. Is it still
available?

You can download it from

http://localhost:80/frobozz/products/lobotomy/

They're CP/M WordStar files; pull your old Osborne out of
the closet and you'll be able to read them. (Scrolling
that tiny screen is sort of a pain, though.)
 
I

Ioannis Vranos

Kenny said:
And:

1) How to declare main() { Always a hit! }

Easy. Under C90:

int main(), int main(void), int main(int argc, char *argv[]), int
main(int argc, char **argv), and those also with no return type
(implicit int).

2) Why not to cast the return value of *alloc()

That's it folks. Enjoy!


malloc() doesn't need a cast in C, it needs in C++, because in C there
is implicit conversion of void * to any other pointer type, but not in
C++ where it requires a cast.
 
R

Richard

Ioannis Vranos said:
Kenny said:
And:

1) How to declare main() { Always a hit! }

Easy. Under C90:

int main(), int main(void), int main(int argc, char *argv[]), int
main(int argc, char **argv), and those also with no return type
(implicit int).

2) Why not to cast the return value of *alloc()

That's it folks. Enjoy!


malloc() doesn't need a cast in C, it needs in C++, because in C there
is implicit conversion of void * to any other pointer type, but not in
C++ where it requires a cast.

I think you miss the point. Kenny was being sarcastic because the clique
are normally in a race to see who can answer this first in the most
confusing and condescending manner.
 
K

Kenny McCormack

Ioannis Vranos said:
Kenny said:
And:

1) How to declare main() { Always a hit! }

Easy. Under C90:

int main(), int main(void), int main(int argc, char *argv[]), int
main(int argc, char **argv), and those also with no return type
(implicit int).

2) Why not to cast the return value of *alloc()

That's it folks. Enjoy!


malloc() doesn't need a cast in C, it needs in C++, because in C there
is implicit conversion of void * to any other pointer type, but not in
C++ where it requires a cast.

I think you miss the point. Kenny was being sarcastic because the clique
are normally in a race to see who can answer this first in the most
confusing and condescending manner.

He's kind of made your point for you, didn't he?
 
R

Richard

Ioannis Vranos said:
Kenny McCormack wrote:

And:

1) How to declare main() { Always a hit! }

Easy. Under C90:

int main(), int main(void), int main(int argc, char *argv[]), int
main(int argc, char **argv), and those also with no return type
(implicit int).


2) Why not to cast the return value of *alloc()

That's it folks. Enjoy!


malloc() doesn't need a cast in C, it needs in C++, because in C there
is implicit conversion of void * to any other pointer type, but not in
C++ where it requires a cast.

I think you miss the point. Kenny was being sarcastic because the clique
are normally in a race to see who can answer this first in the most
confusing and condescending manner.

He's kind of made your point for you, didn't he?

Amazing isn't it?
 
I

Ioannis Vranos

Dann said:
--- Module: foo.c (C)
_
printf("%d %d\n", n++, n);
foo.c(8) : Warning 564: variable 'n' depends on order of evaluation

I wonder a bit about this one. Let's consider a simpler version:


#include <stdio.h>


int somefunc(int x)
{
printf("%d\n", x);

return x;
}


int main(void)
{
int x= 1;

somefunc(x++);

return 0;
}



Above, is it well defined that it will be printed "1"?



#include <stdio.h>


int somefunc(int x)
{
printf("%d\n", x);

return x;
}


int main(void)
{
int x= 1;

somefunc( (x++, somefunc(x)) );

return 0;
}


In the above, the expression (x++, somefunc(x)) is evaluated to 2, so I
assume it is guaranteed that it will print "2".
 
R

Richard

Ioannis Vranos said:
I wonder a bit about this one. Let's consider a simpler version:


#include <stdio.h>


int somefunc(int x)
{
printf("%d\n", x);

return x;
}


int main(void)
{
int x= 1;

somefunc(x++);

return 0;
}



Above, is it well defined that it will be printed "1"?

Could you explain your thinking if you thought it would be anything else?
 
B

Ben Bacarisse

Ioannis Vranos said:
I wonder a bit about this one. Let's consider a simpler version:


#include <stdio.h>

int somefunc(int x)
{
printf("%d\n", x);
return x;
}

int main(void)
{
int x= 1;
somefunc(x++);
return 0;
}

Above, is it well defined that it will be printed "1"?

Yes, all well-defined as far as I can see. What might be the problem?
#include <stdio.h>

int somefunc(int x)
{
printf("%d\n", x);
return x;
}

int main(void)
{
int x= 1;
somefunc( (x++, somefunc(x)) );
return 0;
}

In the above, the expression (x++, somefunc(x)) is evaluated to 2, so I
assume it is guaranteed that it will print "2".

Well, it will print "2" twice since there are two calls, but again,
all well-defined. The comma operator has a sequence point between its
two parts so x can be used safely in the right-hard part.
 
C

CBFalconer

Ioannis said:
.... snip ...

int main(void) {
int x= 1;
somefunc( (x++, somefunc(x)) );
return 0;
}

In the above, the expression (x++, somefunc(x)) is evaluated to 2,
so I assume it is guaranteed that it will print "2".

Because that is using the comma operator. However:

somefunc(int x, int y) {printf("%d\n", x);}

int main(void) {
int x = 1;
somefunct(x++, x);
return 0;
}

has no idea whether x++ is executed before or after the x parameter
load. That's why it is illegal.
 
P

pete

Ioannis said:
K&R2 mentions the following:

"printf("%d %d\n", ++n, power(2,n)); /* WRONG */

can produce different results with different compilers, depending on
whether n is incremented before power is called".

That's why I call it implementation-defined behaviour.

It's unspecified behavior.
The power(2,n) function call, introduces a sequence point
that the other code examples don't have.
This is all about sequence points.
 
P

pete

Richard said:
Ioannis Vranos said:
Kenny said:
And:

1) How to declare main() { Always a hit! }

Easy. Under C90:

int main(), int main(void), int main(int argc, char *argv[]), int
main(int argc, char **argv), and those also with no return type
(implicit int).

2) Why not to cast the return value of *alloc()

That's it folks. Enjoy!


malloc() doesn't need a cast in C, it needs in C++,
because in C there is implicit conversion of void *
to any other pointer type, but not in
C++ where it requires a cast.

I think you miss the point.

Nope. He didn't miss the point. You did.
Kenny was being sarcastic because

Nobody cares about that.
That's the point.
 
H

Harald van Dijk

It's unspecified behavior.
The power(2,n) function call, introduces a sequence point that the other
code examples don't have. This is all about sequence points.

If arguments are evaluated strictly from left to right (nothing wrong
with that), here are the steps:
- evaluate "%d %d\n"
- evaluate ++n
- evaluate 2
- evaluate n
* call power
* call printf

There is not necessarily any sequence point between the evaluation of ++n
and the evaluation of n, unless I'm missing something.
 
P

pete

Dann said:
so does:
printf("%d %d\n", x++, x);

That's undefined, not implementation defined.
There's no sequence points in there.
This one does not.

Of course not.
This is not about freaking out at the sight of an increment operator,
it's about sequence points.
 

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,766
Messages
2,569,569
Members
45,042
Latest member
icassiem

Latest Threads

Top