0

I have some difficulty understanding what is happening with this simple example compiled by two different compilers:

#include <iostream>
using namespace std;

int main()
{
    double x;
    cout << x << endl;
    x += 1.0;
    cout << x << endl;
    return 0;
}

Compiling with g++ it gives

0
1

while compiling with clang++, it gives

6.95279e-310
1

I am sure it is my lack of understanding, but any tips understanding this behaviour would be much appreciated. Is the compiled code produced from clang++ setting x = 0 when it is reassigned, but not when shown with cout? Is this expected behaviour?

Question: Should one always initialise variables because of these differences? What is common practice in C++?

alko989
  • 7,688
  • 5
  • 39
  • 62
  • 9
    It's undefined behavior – AndyG Jan 20 '20 at 16:39
  • 2
    *"Should one always initialise variables"* yes. – Jarod42 Jan 20 '20 at 16:40
  • Variables are generally not initialized in C++. So `x` will have an arbitrary value due to undefined behavior. – perivesta Jan 20 '20 at 16:40
  • If you look at the assembly generated by g++, you will notice it doesn't actually set `x` to `0`. You just happened to get a zero. – ChrisMM Jan 20 '20 at 16:42
  • 1
    Also you should read [this](https://stackoverflow.com/questions/588004/is-floating-point-math-broken) before your start doing any work with floating point numbers. – NathanOliver Jan 20 '20 at 16:42
  • 1
    this is one of the mistakes that AAA (almost always auto) helps to avoid completely, because if you write `auto x = 0;` you cannot forget to initialize `x` – 463035818_is_not_an_ai Jan 20 '20 at 16:43
  • https://stackoverflow.com/a/1910992/14065 – Martin York Jan 20 '20 at 16:44
  • 1
    What output do you expect in the second case? `1.00000....(300 zeros)...00000695279`? – Max Langhof Jan 20 '20 at 16:48
  • @MaxLanghof very good point, did not see that. – alko989 Jan 20 '20 at 16:51
  • @NathanOliver you are right the floating point was my newb mistake, but I suppose the difference between clang and gcc remains, right? – alko989 Jan 20 '20 at 16:52
  • 1
    Not really. When you `double x;`, `x` can have whatever in it. Reading from it before you assign to is is undefined behavior so programs are "correct". The real thing to take away from this is either always initialize your variables, or if you don't, at least don't read from them before you assign something to them. – NathanOliver Jan 20 '20 at 16:53
  • @ChrisMM when I run the g++ version it always gives 0 and the clang++ always some small garbage – alko989 Jan 20 '20 at 16:54
  • The problem is not with either compiler. The problem is your code. It has undefined behavior. The C++ standard allows anything and everything to happen. – Max Langhof Jan 20 '20 at 16:54
  • 1
    @alko989, I'm not doubting that. But tell g++ to output the assembly, and have a gander at it. You'll see that it doesn't set it to anything. – ChrisMM Jan 20 '20 at 17:02
  • 1
    @formerlyknownas_463035818 To be fair, enabling warnings also solves this problem. – HolyBlackCat Jan 20 '20 at 17:05
  • @HolyBlackCat I have to admit that I am not a fan of AAA at all. It is just this point that I completely agree on that it brings an advantage. But yeah warnings can fix this as well – 463035818_is_not_an_ai Jan 20 '20 at 18:14

1 Answers1

1

What you are experiencing is undefined behaviour. In C++ variables are not initialized for you.

The output of your program might be different from compiler to compiler, it might even change it's outcome if you run it multiple times or on a different machine.

Visual Studio 2019 with SDL checks enabled won't even compile this.

So yes you should always initialise variables before using them.

Eric
  • 1,183
  • 6
  • 17
  • 5
    I wouldn't say always. The `int size; cout << "Enter size: "; cin >> size;` idiom is fine. There is no reason to give `size` an initial value here and it wastes CPU cycles. – NathanOliver Jan 20 '20 at 16:56
  • 1
    Visual Studio compiles this fine … it produces warnings only... [See here](https://godbolt.org/z/S8yuAg) – ChrisMM Jan 20 '20 at 17:00
  • @ChrisMM This depends on your settings. I copy & pasted the op's code into an almost fresh install of Visual Studio 2019 and got an compile time error. So i think by default this is an compile time error. It can be turned on and off under "SDL checks" in your C++ / General settings. – Eric Jan 20 '20 at 20:56
  • By default is a warning. SDL checks are off by default. As it should be, since it introduces runtime checks which effect performance. Unless maybe you're in debug mode? I never use debug. – ChrisMM Jan 20 '20 at 21:03