0

In section 9.2 of the book The C++ Programming Language, Bjarne Stroustrup wrote:

Note that a variable defined without an initializer in the global or a namespace scope is initialized by default. This is not the case for local variables or objects created on the free store.

But the following program prints a value of 0:

#include <iostream>
using namespace std;

int main() {
    int x;
    cout << x << endl;
    return 0;
}

Shouldn't it be returning some kind of error?

I use g++ to compile.

Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
Laschet Jain
  • 734
  • 1
  • 8
  • 24
  • 5
    It's *not* initialized. It's value will be *indeterminate*. For you it happens to be zero, for someone else it can be some other seemingly random value. And using indeterminate values in C++, even just reading them like you do, is [*undefined behavior*](http://en.cppreference.com/w/cpp/language/ub). – Some programmer dude Mar 18 '18 at 10:05
  • 2
    You have a slight logical fallacy there. Nothing makes 0 any less random than others values. – StoryTeller - Unslander Monica Mar 18 '18 at 10:06
  • @Someprogrammerdude Thanks. – Laschet Jain Mar 18 '18 at 10:06
  • @Someprogrammerdude Is the memory allocated as soon as the variable is declared or after it's assigned? – Laschet Jain Mar 18 '18 at 10:07
  • But there is no assignment being made. The value of `x` will in reality just be what happens to be in the memory that is now occupied by `x`. You don't know where this memory is located, or what the contents will be. All you know is that there is `sizeof x` bytes allocated somewhere for the variable. – Some programmer dude Mar 18 '18 at 10:11
  • 1
    Never ever compile anything without the `-Wall` compiler option. A good starter set is `-Wall -Werror -pedantic-errors`, highly recommended. – n. m. could be an AI Mar 18 '18 at 10:12
  • Possible duplicate of [Variable initialization in C++](https://stackoverflow.com/questions/2218254/variable-initialization-in-c) – xskxzr Mar 18 '18 at 10:12
  • @xskxzr I think mine is specific to local variables. The other OP didn't mention that. – Laschet Jain Mar 18 '18 at 10:15
  • @Someprogrammerdude Can't this be known by via a pointer to that variable. I just tried and it gave me some address. – Laschet Jain Mar 18 '18 at 10:32
  • The variable `x` have a location. But the contents of that location is indeterminate. You need to learn the difference between a variables location and its value. – Some programmer dude Mar 18 '18 at 10:33
  • @Someprogrammerdude I don't remember where but I read that memory is not allocated when a variable is declared, it's allocated when it's first assigned. Is this wrong? If not, why is memory allocated to this variable. – Laschet Jain Mar 18 '18 at 10:35
  • Okay, then you need to learn the difference between *declaration* and *definition*. A variable gets space in memory with its *definition*. – Some programmer dude Mar 18 '18 at 10:36
  • I suggest you get [some good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) to read. – Some programmer dude Mar 18 '18 at 10:37
  • @Someprogrammerdude But here I declared the variable and didn't define it. Right? – Laschet Jain Mar 18 '18 at 10:37
  • Since local variables are not defined without an initializer. – Laschet Jain Mar 18 '18 at 10:38
  • Let us [continue this discussion in chat](https://chat.stackoverflow.com/rooms/167041/discussion-between-lashit-jain-and-some-programmer-dude). – Laschet Jain Mar 18 '18 at 10:40
  • 1
    A *declaration* is you telling the compiler that something exists somewhere. A *definition* is telling the compiler that something exists right here. A definition may also be a declaration, and in your case for the variable `x` you have both. Really, don't just guess, get a good book. – Some programmer dude Mar 18 '18 at 11:27
  • @Someprogrammerdude Since local variables are not defined without an initializer, doesn't it mean in my case it's not a definition, just a declaration? – Laschet Jain Mar 18 '18 at 12:11
  • No you're still misunderstand me! A definition doesn't need an initialization. Doesn't matter when or where the definition is. Stop just guessing and get a book! – Some programmer dude Mar 18 '18 at 12:22
  • Don't "A definition doesn't need an initialization" in local variable's context and "Local Variables are not defined without an initializer" contradict? Where am I going wrong? – Laschet Jain Mar 18 '18 at 12:28
  • @LashitJain: Why do you keep ignoring the "get a book" part? C++ is an incredibly complex programming language. You cannot learn it via Stack Overflow comments. – Christian Hackl Mar 18 '18 at 12:47
  • @ChristianHackl I am reading a book as specified in the question. But the statement that someprogrammerdude gave and the one I read in the book contradict. Therefore I'm asking the question (the comment one). – Laschet Jain Mar 18 '18 at 12:49
  • Nevertheless, I'll read more from the book and try figuring this out. If not possible I'll raise a question later. Thank you guys for the help and insightful comments. – Laschet Jain Mar 18 '18 at 12:52

3 Answers3

6

But the following program prints a value of 0 on my terminal.

It has undefined behaviour because the cout line tries to read from an uninitialised int. Any output you see, and in fact any behaviour at all, is not guaranteed.

Shouldn't it be returning some kind of error?

No, that's not how undefined behaviour works. You may or may not see an error.

Christian Hackl
  • 27,051
  • 3
  • 32
  • 62
5

x is uninitialized, so your snippet actually has an undefined behavior.


Shouldn't it be returning some kind of error?

g++ doesn't warn of uninitialized values by default.

You need the -Wuninitialized option if you want your compiler to show a warning:

g++ -Wuninitialized your_file.c

You should probably use the -Wall option instead to enable this warning alongside lots of other useful warnings.

More information on warning options here

Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
2

Shouldn't it be returning some kind of error?

No, it should not, but this error is detectable by Valgrind:

$ valgrind --track-origins=yes ./a.out
==4950== Memcheck, a memory error detector
==4950== Copyright (C) 2002-2017, and GNU GPL'd, by Julian Seward et al.
==4950== Using Valgrind-3.13.0 and LibVEX; rerun with -h for copyright info
==4950== Command: ./a.out
==4950== 
==4950== Conditional jump or move depends on uninitialised value(s)
==4950==    at 0x4F4444A: std::ostreambuf_iterator<char, std::char_traits<char> > std::num_put<char, std::ostreambuf_iterator<char, std::char_traits<char> > >::_M_insert_int<long>(std::ostreambuf_iterator<char, std::char_traits<char> >, std::ios_base&, char, long) const (locale_facets.tcc:874)
==4950==    by 0x4F504C4: put (locale_facets.h:2371)
==4950==    by 0x4F504C4: std::ostream& std::ostream::_M_insert<long>(long) (ostream.tcc:73)
==4950==    by 0x40076D: main (t.cpp:5)
==4950==  Uninitialised value was created by a stack allocation
==4950==    at 0x400757: main (t.cpp:3)
==4950== 

This part of Valgrind output clearly states that:

==4950==  Uninitialised value was created by a stack allocation
==4950==    at 0x400757: main (t.cpp:3)
==4950== 
Ronan Boiteau
  • 9,608
  • 6
  • 34
  • 56
ks1322
  • 33,961
  • 14
  • 109
  • 164