Kindred
Kindred

Reputation: 1269

What's wrong with this example with string literal?

I'm reading an answer from this site which says the following is undefined

char *fubar = "hello world";
*fubar++; // SQUARELY UNDEFINED BEHAVIOUR!

but isn't that fubar++ is done first, which means moving the pointer to e, and *() is then done, which means extract the e out. I know this is supposed to be asked on chat (I'm a kind person) but no one is there so I ask here to attract notice.

Upvotes: 2

Views: 491

Answers (2)

Stephan Lechner
Stephan Lechner

Reputation: 35154

The code shown is clearly not undefined behaviour, since *fubar++ is somewhat equal to char result; (result = *fubar, fubar++, result), i.e. it increments the pointer, and not the dereferenced value, and the result of the expression is the (dereferenced) value *fubar before the pointer got incremented. *fubar++ actually gives you the character value to which fubar originally points, but you simply make no use of this "result" and ignore it.

Note, however, that the following code does introduce undefined behaviour:

char *fubar = "hello world";
(*fubar)++;

This is because this increments the value to which fubar points and thereby manipulates a string literal -> undefined behaviour.

When replacing the string literal with an character array, then everything is OK again:

int main() {

    char test[] = "hello world";
    char* fubar = test;
    (*fubar)++;
    printf("%s\n",fubar);
}

Output:

iello world

Upvotes: 5

Some programmer dude
Some programmer dude

Reputation: 409166

The location of the ++ is the key: If it's a suffix (like in this case) then the increment happens after.

Also due to operator precedence you increment the pointer.

So what happens is that the pointer fubar is dereference (resulting in 'h' which is then ignored), and then the pointer variable fubar is incremented to point to the 'e'.

In short: *fubar++ is fine and valid.

If it was (*fubar)++ then it would be undefined behavior, since then it would attempt to increase the first characters of the string. And literal strings in C are arrays of read-only characters, so attempting to modify a character in a literal string would be undefined behavior.


The expression *fubar++ is essentially equal to

char *temporary_variable = fubar;
fubar = fubar + 1;
*temporary_variable;  // the result of the whole expression

Upvotes: 6

Related Questions