[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c

Undefined behavior

DonStarr

8/13/2008 8:55:00 PM

I've read the FAQ, and I believe I know the answer to the below.
However, I've been involved in a rather "spirited" discussion on a
platform-specific mailing list and want to ensure that I'm "right"
before I make a further fool of myself...

int func( int x )
{
return x;
}

int main( int argc, char *argv[] )
{
int len = 5;
int arr[ 10 ];

arr[ len++ ] = func( len ); /* problem line */

return 0;
}

The above code was posted by someone who believed he had a problem
with the compiler, particularly the line with the comment. In previous
usage of that "construct", the argument to the function had always
been 5. Now, though, he's sometimes seeing 6. Which argument value he
sees seems to depend on other (not listed above) code that might be
executed before or after the commented line.

I maintain that the above results in "undefined behavior", since <len>
is both modified and read (apart from retrieving the value to be
stored) between two sequence points.

It has been pointed out on the "other" mailing list that the function
call results in a sequence point. I maintain that this sequence point
is irrelevant, because:
a) it can only "hit" when the operand on the RHS of the '=' operator
is evaluated, and
b) there's no guarantee that the operand on the RHS will be evaluated
before the operand on the LHS.

I believe that, for the purposes of determining when the side-effect
of the postfix operator ("len++") is "complete", the only sequence
point that matters is the semicolon at the end of the statement. And,
since <len> is both modified and read between that sequence point and
the last, this is Undefined Behavior.

Am I right?

-Don
--
remove roman numerals from email
3 Answers

Harald van D?k

8/13/2008 9:05:00 PM

0

On Wed, 13 Aug 2008 13:54:41 -0700, DonStarr wrote:
> [...]
> arr[ len++ ] = func( len ); /* problem line */
> [...]
> It has been pointed out on the "other" mailing list that the function
> call results in a sequence point. I maintain that this sequence point is
> irrelevant, because:
> a) it can only "hit" when the operand on the RHS of the '=' operator
> is evaluated, and
> b) there's no guarantee that the operand on the RHS will be evaluated
> before the operand on the LHS.

This is mostly correct.

> I believe that, for the purposes of determining when the side-effect of
> the postfix operator ("len++") is "complete", the only sequence point
> that matters is the semicolon at the end of the statement. And, since
> <len> is both modified and read between that sequence point and the
> last, this is Undefined Behavior.

There are four relevant sequence points:

1- start
2- function call: func
3- function return: func
4- semicolon

The increment of len may happen either between 1 and 2, or between 3 and
4. If it happens between 1 and 2, then there is a problem. On the other
hand, if it happens between 3 and 4, then all is fine, because there will
have been a sequence point between the read and the store. However, there
is no requirement on implementations to choose one or the other, or to
document how the choice is made, and there is no possibility for a correct
program to detect which choice is made. Because of that, the program
should be modified so that the increment of len is guaranteed to follow
the call to func.

> Am I right?

Essentially, yes.

Flash Gordon

8/13/2008 9:17:00 PM

0

DonStarr wrote, On 13/08/08 21:54:
> I've read the FAQ, and I believe I know the answer to the below.
> However, I've been involved in a rather "spirited" discussion on a
> platform-specific mailing list and want to ensure that I'm "right"
> before I make a further fool of myself...

So you decided to see if you could make a fool of yourself here? ;-)

> int func( int x )
> {
> return x;
> }
>
> int main( int argc, char *argv[] )
> {
> int len = 5;
> int arr[ 10 ];
>
> arr[ len++ ] = func( len ); /* problem line */
>
> return 0;
> }
>
> The above code was posted by someone who believed he had a problem
> with the compiler, particularly the line with the comment. In previous
> usage of that "construct", the argument to the function had always
> been 5. Now, though, he's sometimes seeing 6. Which argument value he
> sees seems to depend on other (not listed above) code that might be
> executed before or after the commented line.
>
> I maintain that the above results in "undefined behavior", since <len>
> is both modified and read (apart from retrieving the value to be
> stored) between two sequence points.

You are correct.

> It has been pointed out on the "other" mailing list that the function
> call results in a sequence point. I maintain that this sequence point
> is irrelevant, because:
> a) it can only "hit" when the operand on the RHS of the '=' operator
> is evaluated, and

It's even narrower than that. It can only be "hit" when the actual
function call occurs which is obviously after the arguments have been
evaluated.
--
Flash Gordon
> b) there's no guarantee that the operand on the RHS will be evaluated
> before the operand on the LHS.

Correct.

> I believe that, for the purposes of determining when the side-effect
> of the postfix operator ("len++") is "complete", the only sequence
> point that matters is the semicolon at the end of the statement.

Correct.

> And,
> since <len> is both modified and read between that sequence point and
> the last, this is Undefined Behavior.
>
> Am I right?

You are correct.

August Karlstrom

8/14/2008 11:56:00 AM

0

DonStarr wrote:
> I've read the FAQ, and I believe I know the answer to the below.
> However, I've been involved in a rather "spirited" discussion on a
> platform-specific mailing list and want to ensure that I'm "right"
> before I make a further fool of myself...
>
> int func( int x )
> {
> return x;
> }
>
> int main( int argc, char *argv[] )
> {
> int len = 5;
> int arr[ 10 ];
>
> arr[ len++ ] = func( len ); /* problem line */
>
> return 0;
> }
>
> The above code was posted by someone who believed he had a problem
> with the compiler, particularly the line with the comment.

Just tell him/her to not write such constructs.

arr[len] = func(len);
len++;

or

len++;
arr[len] = func(len);

is the way to go if you want maintainable code.


August


http://en.wikipedia.org/wiki/Command-query_...