What's wrong with this example with string literal?
up vote
2
down vote
favorite
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.
c string increment
|
show 8 more comments
up vote
2
down vote
favorite
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.
c string increment
1
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
1
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
1
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
1
Oops. I was not aware about this. ;-)
– Scheff
yesterday
1
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday
|
show 8 more comments
up vote
2
down vote
favorite
up vote
2
down vote
favorite
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.
c string increment
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.
c string increment
c string increment
edited 5 hours ago
asked yesterday
ptr_user7813604
371118
371118
1
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
1
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
1
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
1
Oops. I was not aware about this. ;-)
– Scheff
yesterday
1
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday
|
show 8 more comments
1
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
1
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
1
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
1
Oops. I was not aware about this. ;-)
– Scheff
yesterday
1
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday
1
1
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
1
1
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
1
1
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
1
1
Oops. I was not aware about this. ;-)
– Scheff
yesterday
Oops. I was not aware about this. ;-)
– Scheff
yesterday
1
1
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday
|
show 8 more comments
2 Answers
2
active
oldest
votes
up vote
6
down vote
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
1
but wait++(postfix)
has the highest precedence while*
not...
– ptr_user7813604
yesterday
1
@ptr_user7813604*fubar++
is equal to*(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.
– Osiris
yesterday
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
*fubar++
is equal to*(fubar++)
which is (mostly) equal to*fubar; fubar++;
.
– Osiris
yesterday
|
show 1 more comment
up vote
5
down vote
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("%sn",fubar);
}
Output:
iello world
add a comment |
2 Answers
2
active
oldest
votes
2 Answers
2
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
6
down vote
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
1
but wait++(postfix)
has the highest precedence while*
not...
– ptr_user7813604
yesterday
1
@ptr_user7813604*fubar++
is equal to*(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.
– Osiris
yesterday
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
*fubar++
is equal to*(fubar++)
which is (mostly) equal to*fubar; fubar++;
.
– Osiris
yesterday
|
show 1 more comment
up vote
6
down vote
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
1
but wait++(postfix)
has the highest precedence while*
not...
– ptr_user7813604
yesterday
1
@ptr_user7813604*fubar++
is equal to*(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.
– Osiris
yesterday
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
*fubar++
is equal to*(fubar++)
which is (mostly) equal to*fubar; fubar++;
.
– Osiris
yesterday
|
show 1 more comment
up vote
6
down vote
up vote
6
down vote
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
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
edited yesterday
answered yesterday
Some programmer dude
291k24241400
291k24241400
1
but wait++(postfix)
has the highest precedence while*
not...
– ptr_user7813604
yesterday
1
@ptr_user7813604*fubar++
is equal to*(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.
– Osiris
yesterday
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
*fubar++
is equal to*(fubar++)
which is (mostly) equal to*fubar; fubar++;
.
– Osiris
yesterday
|
show 1 more comment
1
but wait++(postfix)
has the highest precedence while*
not...
– ptr_user7813604
yesterday
1
@ptr_user7813604*fubar++
is equal to*(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.
– Osiris
yesterday
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
*fubar++
is equal to*(fubar++)
which is (mostly) equal to*fubar; fubar++;
.
– Osiris
yesterday
1
1
but wait
++(postfix)
has the highest precedence while *
not...– ptr_user7813604
yesterday
but wait
++(postfix)
has the highest precedence while *
not...– ptr_user7813604
yesterday
1
1
@ptr_user7813604
*fubar++
is equal to *(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.– Osiris
yesterday
@ptr_user7813604
*fubar++
is equal to *(fubar++)
. That is also explained in the answer. Note that since it is a postfix operator the pointer is dereferenced before the increment and then the pointer is incremented.– Osiris
yesterday
1
1
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
@Osiris: but he says after or what's the truth...
– ptr_user7813604
yesterday
1
1
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
@ptr_user7813604, ++(postfix) is meaningless and means nothing since you have no additional operand in the brackets.
– SPlatten
yesterday
1
1
*fubar++
is equal to *(fubar++)
which is (mostly) equal to *fubar; fubar++;
.– Osiris
yesterday
*fubar++
is equal to *(fubar++)
which is (mostly) equal to *fubar; fubar++;
.– Osiris
yesterday
|
show 1 more comment
up vote
5
down vote
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("%sn",fubar);
}
Output:
iello world
add a comment |
up vote
5
down vote
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("%sn",fubar);
}
Output:
iello world
add a comment |
up vote
5
down vote
up vote
5
down vote
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("%sn",fubar);
}
Output:
iello world
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("%sn",fubar);
}
Output:
iello world
edited yesterday
answered yesterday
Stephan Lechner
24.4k21738
24.4k21738
add a comment |
add a comment |
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53409238%2fwhats-wrong-with-this-example-with-string-literal%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
1
Do you want to increment the address or the content, for content: (*fubar)++; For the address fubar++;
– SPlatten
yesterday
1
@SPlatten: I want neither, I just want to know whether it would lead to undefined behaviour as the answer said...
– ptr_user7813604
yesterday
1
You have no assignment so there is no point in the '*'.
– SPlatten
yesterday
1
Oops. I was not aware about this. ;-)
– Scheff
yesterday
1
Lesson learned: adhere to the rule of never mixing ++ with other operators in the same expression. It is a bad thing to do for multiple reasons: readability, maintainability, potentially undefined behavior,
– Lundin
yesterday