samuelbrody1249
samuelbrody1249

Reputation: 4767

Using postfix/suffix operator in an assignment

Is it acceptable to have a post/prefix operator on the lhs of an assignment operator?

#include<ctype.h>
void to_upper_in_place(char* string)
{
    while(*string++ = toupper(*string));
}

If it is OK, is the previous considered readable C code, or should it be turned into something like the following?

#include<ctype.h>
void to_upper_in_place(char* string)
{
    while(*string) {
        *string = toupper(*string);
        string++;
    }
}

Or even:

while(*string = toupper(*string++));

Upvotes: 2

Views: 284

Answers (1)

Steve Summit
Steve Summit

Reputation: 48020

Let's look at several different cases.

(1) (with two different pointers)

*dest++ = toupper(*src++);

This is perfectly ordinary C style.

(2)

*dest = toupper(*src);
src++;
dest++;

This is "longhand" style. You might write it if you were scared of using ++ in a dangerous way. (And a certain amount of caution is indeed justified, as we're about to see.)

(3) (back to the same pointer on lhs and rhs)

*p = toupper(*p);
p++;

This is fine.

(4)

*p++ = toupper(*p);

This is problematic, because p is both used and modified in the same expression, with the modification not depending on the value used. In many/most cases, this pattern renders the expression undefined, and that's a Bad Thing. It ends up being particularly hard to say wheteher this particular case is actually undefined, but for that reason we have to stay on the safe side, and say that (3) is preferable. (For more -- much more -- on this kind of undefined behavior, see this beleaguered old question.)

(5)

*p = toupper(*p++);

This is even worse. It's equally potentially undefined, but if it works at all, it probably increments p too soon.

(6) Yet another arrangement is to put the increment into the loop header, by using a for loop instead:

for(; *p; p++)
    *p = toupper(*p);

This is also fine.

Upvotes: 7

Related Questions