Undefined behaviour

I

Ioannis Vranos

I do not remember if the following is undefined behaviour:

somefunc(i++);


Is it?

Thanks.
 
D

Daniel Pitts

Ioannis said:
I do not remember if the following is undefined behaviour:

somefunc(i++);


Is it?

Thanks.
it depends on somefunc and i.

The following is UB:
#define somefunc(X) x * x

I think this may be UB:
void somefunc(sometype &v) {}

The following is fine:
void somefunc(int v) {}
 
P

peter koch

I do not remember if the following is undefined behaviour:

somefunc(i++);

Is it?

No, not unless there is an overflow resulting from the increment.

/Peter
 
B

Bob Hairgrove

Ioannis said:
I do not remember if the following is undefined behaviour:

somefunc(i++);


Is it?

Thanks.

No. It is not undefined behavior.

The function "somefunc()" receives the original value of i as its
argument, and i is incremented afterwards. The incremented value of i is
not seen by the function called, only by the caller.

If you want the opposite, you need to pre-increment i (i.e.: ++i).
 
J

James Kanze

No. It is not undefined behavior.
The function "somefunc()" receives the original value of i as
its argument, and i is incremented afterwards. The incremented
value of i is not seen by the function called, only by the
caller.

That's actually a little ambiguous, the way you wrote it.
Calling a function is a sequence point, so the actual
incrementation of i will take place before the function is
called (although the argument passed to the function will be the
value of i before the incrementation). And if the variable i is
visible within the function (a global, for example), then
somefunc will see the incremented value in i (but not as its
argument).
 
D

Daniel Pitts

SG said:
Ioannis said:
somefunc(i++);
[...]

I think this may be UB:
void somefunc(sometype &v) {}

Assuming "i++" returns an rvalue it won't compile.
This is the case for sometype=int.

Cheers!
SG
Right, but sometype may not follow proper semantics for operator++, so
that's why I thought it might be UB.
 
I

Ioannis Vranos

I think this is undefined behaviour though:

void somefunc(int x, int y);

somefunc(++i, i);
 
D

Daniel Pitts

Ioannis said:
I think this is undefined behaviour though:

void somefunc(int x, int y);

somefunc(++i, i);
That is indeed UB.

the order that the arguments are evaluated is undefined.
int i = 0;
somefunc(++i, i) might call somefunc(0,0), or somefunc(0,1).
 
S

Stefan Ram

Daniel Pitts said:
That is indeed UB.
the order that the arguments are evaluated is undefined.
int i = 0;
somefunc(++i, i) might call somefunc(0,0), or somefunc(0,1).

By this reason, it does not have to invoke undefined behavior,
it also might invoke merely »unspecifed behavior«.

I know »f(++i,++i)« to invoke undefined behavior, but here
an object is attempted to be /modified twice/ between two
sequence points. This is not the case for »f(++i,i)«.

ISO/IEC 14882:2003(E) says:

(0) »Between the previous and next sequence point a scalar
object shall have its stored value modified at most once
by the evaluation of an expression.«

(1) »Furthermore, the prior value shall be accessed only to
determine the value to be stored.«

ISO/IEC 14882:2003(E), 5#4

(0) does not apply to »f(++i,i)«.

(1) seems somewhat cryptic to me. For example, it seems to
depend on the implementation. If the second »i« in »f(++i,i)«
does refer to the prior value (which might happen in some
C++ implementations), then (1) does apply. But in some implementations
it might refer to the post value. Then, (1) would not apply?

Also, in »printf( "%d", i )« the value of i is /not/ accessed
to determine a »value to be stored« somewhere, but it is
accessed between two sequence points. So, does (1) forbid
this?

There also is this example:

»i = ++i + 1; // the behavior is unspecified«

ISO/IEC 14882:2003(E), 5#4

(Saying that this is unspecified does not exclude that it is
also undefined. But is it?)
 
J

James Kanze

That is indeed UB.
the order that the arguments are evaluated is undefined.
int i = 0;
somefunc(++i, i) might call somefunc(0,0), or somefunc(0,1).

Or somefunc( 42, 53 ). Or it might not call somefunc at all.
It might core dump. Or send an insulting email to your boss.

If the compiler can prove that the line of code will actually be
executed, the code might not even compile.
 
J

James Kanze

By this reason, it does not have to invoke undefined
behavior, it also might invoke merely »unspecifed behavior«.
I know »f(++i,++i)« to invoke undefined behavior, but here
an object is attempted to be /modified twice/ between two
sequence points. This is not the case for »f(++i,i)«.
ISO/IEC 14882:2003(E) says:
(0) »Between the previous and next sequence point a scalar
object shall have its stored value modified at most once
by the evaluation of an expression.«
(1) »Furthermore, the prior value shall be accessed only to
determine the value to be stored.«
ISO/IEC 14882:2003(E), 5#4
(0) does not apply to »f(++i,i)«.
(1) seems somewhat cryptic to me. For example, it seems to
depend on the implementation. If the second »i« in
»f(++i,i)« does refer to the prior value (which might happen
in some C++ implementations), then (1) does apply. But in
some implementations it might refer to the post value. Then,
(1) would not apply?

If any legal ordering would result in undefined behavior, the
behavior is undefined. The very next sentence after (1): "The
requirements of this paragraph shall be met for each allowable
ordering of the subexpressions of a full expression; otherwise
the behavior is undefine.

The wording in the current draft has changed place (to §1.9,
"Program execution") and has been completely reworded, but the
effects (at least in a single threaded program) are the same:

Except where noted, evaluations of operands of
individual operators and of subexpressions of individual
expressions are unsequenced. [ Note: In an expression
that is evaluated more than once during the execution of
a program, unsequenced and indeterminately sequenced
evaluations of its subexpressions need not be performed
consistently in different evaluations. ---end note ]
The value computations of the operands of an operator
are sequenced before the value computation of the result
of the operator. If a side effect on a scalar object is
unsequenced relative to either another side effect on
the same scalar object or a value computation using the
value of the same scalar object, the behavior is
undefined.
Also, in »printf( "%d", i )« the value of i is /not/
accessed to determine a »value to be stored« somewhere, but
it is accessed between two sequence points. So, does (1)
forbid this?

The wording could be (and will be, see above) better. In fact,
you've been mislead in your break-down above: it sould be:

(0) »Between the previous and next sequence point
(0a) a scalar object shall have its stored value
modified at most once by the evaluation of an
expression.«

(0b) »Furthermore, the prior value shall be accessed
only to determine the value to be stored.«

The "furthermore" attaches the second sentence to the first (and
under the rules of English punctuation I learned, there should
only be one sentence, with the period replaced by a semi-colon).
But all of the interpretations of the standard I've seen or
heard have the "Between the previous and next sequence point"
applying to both restrictions (except that the "furthermore"
only applies if the stored value is modified).

The wording is, I grant you, horrible, but I don't think any
other interpretation of it makes sense.
There also is this example:
»i = ++i + 1; // the behavior is unspecified«
ISO/IEC 14882:2003(E), 5#4
(Saying that this is unspecified does not exclude that it is
also undefined. But is it?)

That's DR 351. The resolution was to change both instances of
"unspecified" to "undefined" in the example.
 

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
474,164
Messages
2,570,898
Members
47,439
Latest member
shasuze

Latest Threads

Top