1
#include <iostream>
using namespace std;
int main()
{
    int intVar = 1500000000;                 //1,500,000,000 
    intVar = (intVar * 10) / 10;             //result too large 
    cout << "intVar = " << intVar << endl;   //wrong answer
    intVar = 1500000000;                     //cast to double 
    intVar = (static_cast<double>(intVar) * 10) / 10; 
    cout << "intVar = " << intVar << endl;   //right answer return 0;
    return 0;
}

Output I expected was this: intVar = 211509811 intVar = 1500000000

The output: intVar = 1500000000 intVar = 1500000000

Alex Guteniev
  • 12,039
  • 2
  • 34
  • 79
  • 1
    Without doing the maths I would say Signed Overflow which is UB https://godbolt.org/z/ePG4sPx6a – Richard Critten Jun 27 '21 at 10:50
  • C++20 requires two's complement but overflow is still UB, have a read of https://stackoverflow.com/questions/57363324/ramifications-of-c20-requiring-twos-complement – Richard Critten Jun 27 '21 at 10:56
  • One issue with analysing the above code is you have UB in a single code path - the compiler is allow to do anything at all (eg remove all the code) if it detects UB (which it can easily do in this case). If you could modify the question to not have UB we might have more chance analysing it. [Old New Thing - Undefined behavior can result in time travel](https://devblogs.microsoft.com/oldnewthing/20140627-00/?p=633) – Richard Critten Jun 27 '21 at 10:59
  • Please tell me what is UB? I am a beginner. Should I delete the question? – BURHANUDDINALIASGHAR EZZI Jun 27 '21 at 11:07
  • This code was taken from: OOP in C++ by Robert Lafore – BURHANUDDINALIASGHAR EZZI Jun 27 '21 at 11:08
  • UB is short for __Undefined Behaviour__ it makes the entire program invalid and not subject to analysis - all you can do is remove it, see https://en.cppreference.com/w/cpp/language/ub Signed integer Overflow (_"//result too large"_ ) is one example of UB. Question is fine. – Richard Critten Jun 27 '21 at 11:08

1 Answers1

0

Why is the output the same both times?

If you look at this compiled assembly of your code snippet, you can see, that the line in question (intVar = (intVar * 10) / 10;, line 6 in the input) is completely removed. As Richard Critten mentioned in the comments, this is perfectly legal for the compiler to do in the case of undefined behavior (signed overflow).

In other words: Because the line of code causes undefined behavior, the compiler removes it and it is never executed. As you expected the same value in intVal before and after this line, you never noticed that it was actually removed.

Image for future reference:

enter image description here

To elaborate on your actual question in the title:

Do intermediate static_cast in c++ have an effect?

Yes, as you can see in your code snippet, the cast to double allows the CPU do perform the calculation using the IEEE 754 standard for floating point numbers. These numbers are less precise (there are rounding errors) but allow a much wider range of values. In your case, the CPU does:

  1. Convert the int to double
  2. Multiply it by 10 which results in 1.5e10 (larger than the maximum int 2,147,483,647)
  3. Divide it by 10 which results in 1.5e9 (fits in a 32 bit int again)
  4. Convert it back to int (implicit due to the type of intVar)
Peter
  • 21
  • 3