Does operator precedence differ in C ++ for pointers and iterators?

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; } 

he concludes:

 abcd bcd 

if we separate the assignment operation and the increment operator:

 while(it != end) { *it = tolower(*it); // <-- incr before assignment ? it++; } 

the conclusion will be as expected.

What is wrong with the source code?

 $ g++ --version g++ (GCC) 3.4.4 (cygming special, gdc 0.12, using dmd 0.125) Copyright (C) 2004 Free Software Foundation, Inc. 
+6
c ++ stl
source share
3 answers

The problem is that the evaluation order of the operator= arguments operator= not specified. This complies with C ++ Standard 5.2.2 / 8. Consider the following:

 *it++ = tolower(*it); 

equally

 operator=( *it++, tolower(*it) ); 

Now *it++ can be computed before tolower(*it) and vice versa.

+9
source share
 *it++ = tolower(*it); *p++ = tolower(*p); 

Both of these lines refer to undefined behavior. You cannot change the value of a variable more than once in one of the operators (++ modifies once, operator = modifies twice).

So the fact that you get different values โ€‹โ€‹is not surprising.

+2
source share

Grammar works exactly the same for pointers and iterators. The operations assumed by the operators turn into function calls for objects of the class type (for example, most iterators).

The problem with your code is not related to operator precedence, although in both of these lines there is no sequence between the increment operation and the second reading of the same variable, which is incremented elsewhere in the statement. Because of this, you have undefined behavior so that it can see any behavior of your program, including the results that you see.

 *p++ = tolower(*p); *it++ = tolower(*it); 

You need to reformulate this statement in such a way as to determine the sequence. I assume you want something like this.

 char c = tolower(*p); *p++ = c; 
+2
source share

All Articles