Implementation-defined behaviour

P

pete

santosh said:
Ioannis said:
santosh said:
Ioannis Vranos wrote:

AFAIK the following is implementation-defined behaviour, am I
right?:

#include <stdio.h>

int main(void)
{
int n= 0;
printf("%d\n", n++);
return 0;
}

I don't think so.

There are similar examples at 2.12 of K&R2.


Two quotes from there:

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


"One unhappy situation is typified by the statement

a= i++;"


Well these examples are different from what you have shown above. The
first example above invokes unspecified behaviour while the second one
invokes undefined behaviour. The example in your first post does
neither as far as I can see.


That's the way that I see it too.
 
C

CBFalconer

pete said:
Ioannis Vranos wrote:
.... snip ...


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.

Not quite. Also order of parameter evaluation. The power function
can be called before the ++n is executed, or the reverse. As K&R
pointed out.
 
P

pete

CBFalconer said:
Not quite. Also order of parameter evaluation.

By "this" I was refering to OP's confusion
about what was undefined
versus implementation defined and unspecified behavior.
 
P

pete

Harald said:
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

The call to printf starts before any of its arguments are evaluated.
power returns before printf does.
There is not necessarily
any sequence point between the evaluation of ++n
and the evaluation of n, unless I'm missing something.

There are only two different outputs that the above quoted
C statement can produce.
The choices need not be documented.
That's unspecified behavior.
 
K

Keith Thompson

CBFalconer said:
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.

Please consider being more cautious with the word "illegal". The C
standard doesn't even use the word (except in a footnote referring to
an "illegal instruction").

If I were going to use the word "illegal" with respect to C code, I'd
reserve it for constructs that require a diagnostic, namely syntax
errors and constraint violations. (I'm not sure about applying it to
#error.)
 
H

Harald van Dijk

Harald van =?UTF-8?b?RMSzaw==?= wrote:

[ printf("%d %d\n", ++n, power(2,n)); ]
The call to printf starts before any of its arguments are evaluated.

What matters is when the call to power starts, as that is the only
possible sequence point between the evaluation of ++n and n. I don't
believe it starts before its arguments are evaluated. The requirement of
a sequence point "before the actual call" is what allows

int a;
int f(int ignored) { return a; }
int g(void) { return f(++a); }

where g() must run as

- evaluate ++a
* call f
- evaluate a
- return

Are you saying this too is instead run as

* call f
- evaluate ++a
- evaluate a
- return

? If so, where is the sequence point between evaluation of ++a and
evaluation of a? If there is none, the behaviour would be undefined, and
I'm fairly confident the behaviour is well-defined here.

The relevant text in the standard is
"The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is unspecified,
but there is a sequence point before the actual call."
I've always read "the actual call" as the point where control transfers
to the called function (typically, when the generated BSR instruction or
equivalent is reached).
power returns before printf does.


There are only two different outputs that the above quoted C statement
can produce.
The choices need not be documented.
That's unspecified behavior.

If you're correct about when the call starts, then I agree the behaviour
is unspecified. Otherwise, if there is no sequence point between the
evaluation of ++n and n, there are no restrictions on the behaviour, as
it is explicitly undefined.
 
F

Flash Gordon

pete wrote, On 29/03/08 01:27:
The call to printf starts before any of its arguments are evaluated.
power returns before printf does.

That is not what the standard says. The standard says:
4 An argument may be an expression of any object type. In preparing for
the call to a function, the arguments are evaluated, and each
parameter is assigned the value of the corresponding argument.81)

It goes on to say:
10 The order of evaluation of the function designator, the actual
arguments, and subexpressions within the actual arguments is
unspeciï¬ed, but there is a sequence point before the actual call.

So in the above evaluating the parameters to the power function is
explicitly *required* to take place before the sequence point of calling
the function.
There are only two different outputs that the above quoted
C statement can produce.
The choices need not be documented.
That's unspecified behavior.

No, it is undefined behaviour because there is no sequence point between
evaluating the n passed to power and the n++ which is passed to printf.
 
H

Harald van Dijk

[snip]

So in the above evaluating the parameters to the power function is
explicitly *required* to take place before the sequence point of calling
the function.

Evaluation of the parameters is not possible until power is actually
called, but evaluation of the arguments must take place earlier. :)
 
H

Herbert Rosenau

Yes, all well-defined as far as I can see. What might be the problem?

No, It gives undefined behavior.
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.
No, it is undefined because the sequence the parameters are evulated
is simply undefined, so it is not defined when x++ will be evaluated.
It is open to the implementation when the ++ will be done. No, the
comma here is not the comma operator but only a separator. There is no
sequence point between the arguments to somefunc.

There is a sequence point after the parameter of the inner somefunc is
evaluated and before the inner somefunc is called, but it si undefined
if this sequence point is reached before or after the first parameter
of the outer somefunc is evaluated.

So the call may be
somefunc(1, somefunc(2));
or
somefunc(1, somefunc(1));

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
 
H

Herbert Rosenau

Because that is using the comma operator. However:

Here is no comma operator in sight. The comma here is only a parameter
separator. There are 3 squence pointa:
1. immediately bofre inner somefunc is called
2. immediately before outer somefunc is called
3. when the ';' is reached.

It is undefined when the ++ gets evaluated
- before inner somefunc gets called
- after inner somefunc gets called
- before the parameter of the inner somefunc gets evaluated
- after the parameter of the inner somefunc gets evaluated


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.

It is clearly defined that the original value of x is used as the
value of the first parameter. It is clearly undefined which value the
second parameter will become when somefunc() gets executed.

--
Tschau/Bye
Herbert

Visit http://www.ecomstation.de the home of german eComStation
eComStation 1.2R Deutsch ist da!
 
I

Ioannis Vranos

Herbert said:
No, It gives undefined behavior.

No, it is undefined because the sequence the parameters are evulated
is simply undefined, so it is not defined when x++ will be evaluated.
It is open to the implementation when the ++ will be done. No, the
comma here is not the comma operator but only a separator. There is no
sequence point between the arguments to somefunc.


In the somefunc( (x++, somefunc(x)) ); call, we have one argument:

( x++, somefunc(x) )

which is evaluated from left to right, with value the return value of
somefunc(x) which in this case is 2.


Consider another example:


int x= 1;

/* The external parentheses are not needed */
(x++, printf("%d\n", x));


The above will print 2.
 
W

Willem

Herbert wrote:
) On Fri, 28 Mar 2008 20:43:45 UTC, CBFalconer <[email protected]>
) wrote:
)
)> Ioannis Vranos wrote:
)> >
)> ... 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:
)
) Here is no comma operator in sight.

Look again. Note the extra parens and the fact that somefunc() takes a
single parameter.


SaSW, Willem
--
Disclaimer: I am in no way responsible for any of the statements
made in the above text. For all I know I might be
drugged or something..
No I'm not paranoid. You all think I'm paranoid, don't you !
#EOT
 
L

lawrence.jones

Herbert Rosenau said:
Here is no comma operator in sight. The comma here is only a parameter
separator.

Look again -- there are no parameter separators here, somefunc only
takes one argument. The argument to the outer call to somefunc is a
parenthesized expression containing a comma operator.

-Larry Jones

Whatever it is, it's driving me crazy! -- Calvin
 
B

Ben Bacarisse

Herbert Rosenau said:
No, It gives undefined behavior.

I think you've misread the code. There is a comma operator and only
one argument to somefunc (in both calls).
 
S

Stephen Sprunk

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

It can even produce different results with the same compiler, depending on
the phase of the moon (or, more likely, various optimization settings).
Since there is no sequence point between evaluating arguments to a function
call, the behavior is undefined.
That's why I call it implementation-defined behaviour.

No. "Implementation-defined behavior" means that an implementation is
required to pick one particular behavior and document that's what it does.
That is not the case here.

S
 
S

Stephen Sprunk

[ Excess vertical whitespace removed for easier reading ]

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. There is a sequence point between the evaluation of the arguments and
the function call. Therefore, the only possible output is "1\n".
#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".

That is correct. The difference in this case (vs. your original question)
is that this comma is the comma operator, which guarantees a sequence point,
instead of a mere argument separator, which does not.

S
 
P

pete

Harald said:
Harald van =?UTF-8?b?RMSzaw==?= wrote:

[ printf("%d %d\n", ++n, power(2,n)); ]
The call to printf starts before any of its arguments are evaluated.

What matters is when the call to power starts, as that is the only
possible sequence point between the evaluation of ++n and n. I don't
believe it starts before its arguments are evaluated.

It doesn't. You're right and I'm wrong.

N869
6.5.2.2 Function calls

[#12] EXAMPLE In the function call
(*pf[f1()]) (f2(), f3() + f4())
the functions f1, f2, f3, and f4 may be called in any order.
All side effects have to be completed before the function
pointed to by pf[f1()] is called.
 

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,755
Messages
2,569,537
Members
45,023
Latest member
websitedesig25

Latest Threads

Top