John Humphreys
John Humphreys

Reputation: 39224

C++ Undefined Behavior or Not? (again)

I looked through a pile of the questions and couldn't see this, though I'm sure its on SO somewhere already. So I apologize and figure this will get closed, but hopefully someone will confirm my answer first!

Am I correct in thinking that:

while (--len > -1 && ptr = str[len])

Is well defined (not undefined!) behavior? The way I understand this is that && is a sequence point, and the way short-circuiting would work would mean that --len > -1 should be evaluated first, making the second part not happen if it's unsafe.

I wasn't sure if I was correct in this thought process though.

Upvotes: 2

Views: 169

Answers (5)

hmjd
hmjd

Reputation: 121961

This is defined behaviour as && is a sequence point and the way you understand it is correct. From the linked Wikipedia page:

In C[2] and C++,[3] sequence points occur in the following places:

Between evaluation of the left and right operands of the && (logical AND), || (logical OR), and comma operators. For example, in the expression *p++ != 0 && *q++ != 0, all side effects of the sub-expression *p++ != 0 are completed before any attempt to access q.

This does not, however, ensure that the --len will not result in an index beyond the bounds of str. If str is a null-terminated str you could change to:

while (--len > -1 && len < strlen(str) && ptr = str[len])

Upvotes: 5

Mark B
Mark B

Reputation: 96233

This is actually OK. The key here is that you aren't writing to len more than once.

First you pre-decrement len. Then check if the decremented value of len is at least 0. Next, assign str[len] (using the decremented len) into ptr. Finally check if ptr is non-null, and if so execute the while loop statements.

Note that if len is unsigned -1 will get promoted to unsigned and the loop will pretty much assuredly fail the first iteration. Additionally even if len is signed if it has the minimum int value (std::numeric_limits<int>::min()) decrementing that is unspecified.

Upvotes: 0

2r2w
2r2w

Reputation: 1509

while (--len > -1 && ptr = str[len])

in example for len = 1 ( if len is int ) things goes like that:

1) len = len-1=0
2) ptr = str[0] 

2) is because of decrement of len if first part of if statement. is that what you wanted?

But behaviour is defned and first part will be checked first.

Upvotes: 0

AProgrammer
AProgrammer

Reputation: 52274

You are right to think that ptr = str[len] is not executed if --len > -1 is false (it could be an undefined behavior is len is too big for the indexed array, I assume it isn't what you fear). --len could be an undefined behavior if len is INT_MIN beforehand (again not probable if len is initialized sanely) as overflow of signed arithmetic is an undefined behavior.

Upvotes: 0

trutheality
trutheality

Reputation: 23455

Yes, that is correct. The order is:

  1. len is decremented
  2. (new value of) len is compared to -1
  3. If (2) evaluated to true, ptr = str[len]

Upvotes: 1

Related Questions