The code below demonstrates this difference:
#include <iostream>
#include <string>
int main()
{
char s[] = "ABCD";
std::string str(s);
char *p = s;
while(*p) {
*p++ = tolower(*p); // <-- incr after assignment
}
std::cout << s << std::endl;
std::string::iterator it = str.begin(), end = str.end();
while(it != end) {
*it++ = tolower(*it); // <-- incr before assignment ?
}
std::cout << str << std::endl;
return 0;
}
it produces output:
abcd
bcd
if we separate assignment operation and increment operator:
while(it != end) {
*it = tolower(*it); // <-- incr before assignment ?
it++;
}
the output will be as expected.
What's wrong with the original code?
$ g++ --version
g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125)
Copyright (C) 2004 Free Software Foundation, Inc.
The problem is that the order of evaluation of arguments of operator=
is unspecified. This is according to C++ Standard 5.2.2/8. Consider the following:
*it++ = tolower(*it);
is equal to
operator=( *it++, tolower(*it) );
Now *it++
could be computed before tolower(*it)
and vice versa.
*it++ = tolower(*it);
*p++ = tolower(*p);
Both of these lines invoke undefined behaviour. You cannot modify the value of a variable more than once in a single statement (++ modifies once, operator = modifies twice).
So the fact that you get different values is unsurprising.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With