24

I'm reading 'C++ All-in-One for Dummies' by J. P. Mueller and J. Cogswell and stumbled onto this:

#include <iostream>
using namespace std;
int main()
{
    int ExpensiveComputer;
    int CheapComputer;
    int *ptrToComp;
...

This code starts out by initializing all the goodies involved — two integers and a pointer to an integer.

Just to confirm, this is a mistake and should read '... by declaring', right? It's just strange to me that such basic mistakes still make their way to books.

John Allison
  • 846
  • 1
  • 6
  • 25

4 Answers4

23

From the point of view of the language, this is default initialization. The problem is, they are initialized to indeterminate values.

otherwise, nothing is done: the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.

Default initialization of non-class variables with automatic and dynamic storage duration produces objects with indeterminate values (static and thread-local objects get zero initialized)

Note that any attempt to read these indeterminate values leads to UB.

From the standard, [dcl.init]/7

To default-initialize an object of type T means:

  • If T is a (possibly cv-qualified) class type ([class]), constructors are considered. The applicable constructors are enumerated ([over.match.ctor]), and the best one for the initializer () is chosen through overload resolution ([over.match]). The constructor thus selected is called, with an empty argument list, to initialize the object.

  • If T is an array type, each element is default-initialized.

  • Otherwise, no initialization is performed.

Community
  • 1
  • 1
songyuanyao
  • 147,421
  • 15
  • 261
  • 354
  • 2
    There is a crucial difference between _initialized with an indeterminate value_ and _not initializated_: the former requires a memory store, the latter does not. – Maxim Egorushkin Nov 20 '18 at 11:34
  • @MaximEgorushkin That means the expression of cppreference.com is not accurate either..? – songyuanyao Nov 20 '18 at 11:39
  • Not sure which expression you refer to. – Maxim Egorushkin Nov 20 '18 at 11:41
  • @MaximEgorushkin *the objects with automatic storage duration (and their subobjects) are initialized to indeterminate values.* – songyuanyao Nov 20 '18 at 11:42
  • The expression is accurate. There is a difference between _initialized to_ and _initialized with_ (the one you used). – Maxim Egorushkin Nov 20 '18 at 11:43
  • 5
    @MaximEgorushkin -- that may be formally true, but you cannot write a conforming program that can tell whether a memory store occurred in these cases, so the as-if rule says that they're the same thing. – Pete Becker Nov 20 '18 at 15:33
  • @PeteBecker: Indeed we can go further: The standard says "initialized to an indeterminate value" specifically to allow compilers to skip the memory store (as opposed to zero-initialization, which would not so allow). You can't have "not initialized" at the level of the C abstract machine (unless you are trying to sneak UB in via the "anything not defined is undefined" rule), so you have to say "initialized with indeterminate values" instead. – Kevin Nov 20 '18 at 18:16
  • It's actually worse. They are not initialized, and people have posted examples on stackoverflow where the variables took a value that was outside the range of possible values for a variable of that size. – Joshua Nov 20 '18 at 20:30
7

Yes you are correct.

You declared and defined these variables, you did not initialize them!

PS: What is the difference between a definition and a declaration?

gsamaras
  • 66,800
  • 33
  • 152
  • 256
  • 1
    https://stackoverflow.com/questions/1410563/what-is-the-difference-between-a-definition-and-a-declaration *defines* – Fantastic Mr Fox Nov 20 '18 at 11:19
  • @FantasticMrFox, yes, I read that before posting my question. It was just weird to me that the authors, having such experience (for what it's worth), could write something that's so trivially wrong. Having read **songyuanyao** 's answer, it's not so trivial, though. – John Allison Nov 20 '18 at 11:25
  • FantasticMrFox you are right, updated. @JohnAllison I am not sure, it they wanted to be so on point, they would say default initialize with garbage/random values. Saying initialize a variable and not doing so is **so misleading** and **wrong**. I see what extra information songyuanyao's answer brought to the table, but it's not a boolean one. Anyway, glad you found an answer that fits your thoughts. – gsamaras Nov 20 '18 at 14:29
4

This code both declares and defines three variables but does not initialize them (their values are said to be indeterminate).

A variable declaration only must include keyword extern.

Maxim Egorushkin
  • 119,842
  • 14
  • 147
  • 239
1

Right. Hence, "dummies". :)

We can't even blame this on legacy; historically C programmers would declare* a variable and then "initialize" it later with its first assignment.

But it was never the case that simply declaring a variable, without an initializer, were deemed to be "initializing" it.**

So the wording is just wrong.

* Technically we're talking about definitions, but when we say "declare a variable" we almost always mean defining declarations.

** Though objects with static storage duration do undergo their own zero-initialisation phase before anything else happens, so forgoing initialisation yourself is not a catastrophe in that case. Still, we cannot claim that we have initialised that object.

Lightness Races in Orbit
  • 358,771
  • 68
  • 593
  • 989