0

C++ code is known for being easy to break without noting.

There are lots of examples of undefined behavior (like i = i++ and many more, e.g. in Why are these constructs using pre and post-increment undefined behavior?). Most of them are easy to spot since they usually involve a combination of pre-/post- increments on the same variable and/or sensitive to the summation order.

Here is yet another example, which almost looks like right:

#include <iostream>

int main()
{
    float a[] = {1.f, 2.f, 3.f};
    float* b = a;
    float c = pow(*b++, 2) + pow(*b++, 2);
    std::cout << c << "," << *b; 
}

At the first glance, it doesn't matter which one of pow(*b++, 2) terms will be execute first.

Nevertheless, it prints out "5,3" when compiled and ran in Debug mode (standard Visual Studio console C++ project, all defaults) and prints out "2,3" when doing so in Release mode (tested with both VS2008 and VS2019).

It is straightforward to spot different order of operations produced by the compiler when dealing with the * and ++ operator at the same time.

Without being optimized in Debug mode, the expression pow(*b++, 2) + pow(*b++, 2) is equivalent to:

float c;
c = pow(*b, 2);
b++;
c+= pow(*b, 2);
b++;

Withe the Release optimizations turned on, it behaves like this:

float c;
c = pow(*b, 2);
c+= pow(*b, 2);
b++;
b++;

Considering the example above and alike, my questions are:

  • Is there any compiler setting/warning to detect such situations?

  • If it can't be detected during the compilation, what are the standard Visual Studio tools for dealing with such cases? [I'm looking for the primarily integrated VS-solution, aside from standalone linters]

M0nZDeRR
  • 216
  • 3
  • 7
  • 5
    It's undefined behavior, but regardless, `pow(*b++, 2) + pow(*b++, 2)` is bad code, because it's unclear what it "should" be. The standard tool for preventing such cases is to not write code that's unclear. – Mooing Duck Sep 24 '19 at 00:01
  • Thanks for a hint, but I'm looking for a real (automated) solution, not for an interpretation. C++ is a formal language with a defined operator precedence logic. This expression is ambiguous, but is not undefined behavior (like mentioned in https://stackoverflow.com/questions/367633), since the results are are perfectly stable, just not consistent across different optimization modes. – M0nZDeRR Sep 24 '19 at 00:14
  • 1
    C++ is a formal language, and the operator precidence logic is defined as undefined. Aka: "There is no definition, and writing unclear code may erase the hard drive or catch fire" – Mooing Duck Sep 24 '19 at 00:16
  • @MooingDuck, I'm looking for a formal definition. Do you have any references to add (apart for hard-drive-burner-sdk)? – M0nZDeRR Sep 24 '19 at 00:33
  • Ok @MooingDuck, this is indeed an undefind behvavior case. Here are good (and formal) definitions I was looking for: https://stackoverflow.com/questions/4176328 – M0nZDeRR Sep 24 '19 at 01:32
  • but regardless, not writing bad code works fine until somebody does the opposite :) – M0nZDeRR Sep 24 '19 at 01:38
  • @SamVarshavchik , the question has been edited. Is it still duplicate? – M0nZDeRR Sep 24 '19 at 20:53
  • Minor edits do not materially fix fundamental problems with these kinds of questions. A question of the form "is there a compiler switch to do X" does not need nine whole paragraphs and three code examples before it. A question of the form "is there tool or software that does X" is also off-topic for stackoverflow.com, and is subject to being closed and deleted as being off-topic. See the 4th entry of ["What Can I ask Here](https://stackoverflow.com/help/on-topic) in stackoverflow.com's [help]. – Sam Varshavchik Sep 24 '19 at 22:50
  • Ok @Sam, if the question doesn't worth keeping I totally don't mind if you delete it. I would do it myself, but I can't. Otherwise, if you see a way to improve it let me know how, I'll try to do my best. – M0nZDeRR Sep 24 '19 at 23:33

0 Answers0