Nichtinitialisierung in C++ [] (Nichtinitialisierung in C++), Lektion, Seite 722684
https://www.purl.org/stefan_ram/pub/nichtinitialisierung_c++ (Permalink) ist die kanonische URI dieser Seite.
Stefan Ram
C++-Kurs

Nichtinitialisierung in C++ 

Initialisierer

Als Initialisierer in der Deklaration einer Variablen bezeichnet man den auf den Variablennamen folgenden Teil. Wir zeigen im folgenden einige Beispiele von Deklarationen. Die genaue Bedeutung dieser Deklarationen wird erst später erklärt werden, aber wir können hier schon kennzeichnen, was der Initialisierer ist.

main.cpp

#include <iostream> /* ::std::cout */
#include <ostream> /* << */

int main()
{ /* Initialisierer */
{ int const a {}; ::std::cout << a << '\n'; }
{ int const a = 1; ::std::cout << a << '\n'; }
{ int const a ( 2 ); ::std::cout << a << '\n'; }
{ int const a { 3 }; ::std::cout << a << '\n'; }
{ int const a ={ 4 }; ::std::cout << a << '\n'; }}

::std::cout
0
1
2
3
4

Initialisierung

Als Objekt bezeichnet man in C++  einen Teil des Speichers, welcher den Wert einer Variablen eines bestimmte Typs aufnehmen (speichern) kann. Eine Variable ist ein Name für ein Objekt. Wenn man von einer „Variablen“ spricht meint man oft das von der Variablen benannte Objekt zusammen mit seinem Namen.

Wenn eine Variable angelegt (neu erzeugt) wird, dann wird ein Objekt des Typs der Variablen angelegt (Objekterzeugung) und jenes Objekt der Variablen wird dann oft auch initialisiert. Dies bedeutet, daß das Objekt der Variablen auf einen bestimmten Anfangszustand (Anfangswert) gesetzt wird. Diesen Vorgang nennt man Initialisierung.

Der Initialisierer einer Deklaration kann verwendet werden, um festzulegen, wie ein Objekt genau initialisiert werden soll.

Objekterzeugung

Wie im vorigen Abschnitt schon gesagt, wird beim Anlegen einer Variablen ein Objekt des Typs der Variablen erzeugt. Der Name der Variablen steht dann für dieses Objekt. Wir halten also fest, daß in C++  die gängige Vorgehensweise zum Erzeugen eines Objekts darin besteht, eine Variable des Typs des gewünschten Objekts zu definieren.

Nichtinitialisierung von Variablen fundamentaler Typen

Das folgende Beispiel zeigt eine Definition eines Objekts ohne Verwendung eines Initialisierers.

main.cpp

#include <iostream> /* ::std::cout */
#include <ostream> /* << */

int main(){ int a; ::std::cout << a << '\n'; }

In einem Block deklarierte Variablen haben automatische Lebensdauer. Das heißt, daß das Objekt der Variablen bis zum Ende der Ausführung des Blocks existiert.

Im obigen Programm wird ein Objekt ohne Initialisierer  definiert. Dies bedeutet bei den Typen »int«, »double«, »bool«, und »char«, daß keine Initialisierung  vorgenommen wird: Wenn das zugehörige Objekt mit automatischer Lebensdauer nicht initialisiert wird, dann hat es einen unbestimmten Wert.

In dem obigen Programm wird der Wert des Objekts dann ausgeben. Dazu ist es nötig, den Wert des Objekts auszulesen. Bei einem Objekt mit unbestimmten Wert hat dies undefiniertes Verhalten. Dies bedeutet praktisch, daß solch ein Programm fehlerhaft ist. Solch ein Fehler wird jedoch nicht immer schon bei der Übersetzung eines Programms gemeldet. Er ist auch durch einfache Ausführung des Programms nicht ohne weiteres erkennbar.

Relevante Zitate maßgeblicher Quellen *

If no initializer is specified for an object, the object is default-initialized «, N3797, 8.5p12s1

(If an object does not have class or array type ) “To default-initialize an object of type T means: ” (…) „no initialization is performed “, N3797, 8.5p7

if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.”, N3797, 8.5p12

if the object to which the glvalue refers contains an indeterminate value, the behavior is undefined ”, N3797, 4.1p2

Konstanten

Bei Verwendung von »const« oder »constexpr« kann der Fehler, welcher im Fehlen einer Initialisierung besteht, schon beim Übersetzen diagnostiziert werden, da Konstanten initialisiert werden müssen.

main.cpp

#include <iostream> /* ::std::cout */
#include <ostream> /* << */

int main(){ int const a; ::std::cout << a << '\n'; }

main.cpp

#include <iostream> /* ::std::cout */
#include <ostream> /* << */

int main(){ constexpr int a; ::std::cout << a << '\n'; }

Relevante Zitate maßgeblicher Quellen

A constexpr specifier used in an object declaration declares the object as const. Such an object shall have literal type and shall be initialized.”, N3797, 7.1.5p9s1

If a program calls for the default initialization of an object of a const-qualified type T, T shall be a class type with a user-provided default constructor.”, N3797, 8.5p7s2

Stil

Es wird empfohlen, Variablen stets ausdrücklich zu initialisieren. Die hier beschriebene Nichtinitialisierung sollte also vermieden werden. Wir werden später noch Möglichkeiten dazu behandeln.

Übungsfragen

?   Verhalten eines Programms

main.cpp

#include <iostream> /* ::std::cout */
#include <ostream> /* << */

int main(){ int a; ::std::cout << a << '\n'; }

Welche der folgenden Aussagen treffen bei jeder Ausführung des obenstehenden Programms unter einer C++ -Implementation immer zu?

Anton Das obenstehende Programm gibt 0 aus.
Berta Das obenstehende Programm gibt eine nicht näher bestimmte Zahl aus.
Cäsar Das Verhalten des obenstehenden Programms ist nicht definiert.

Seiteninformationen und Impressum   |   Mitteilungsformular  |   "ram@zedat.fu-berlin.de" (ohne die Anführungszeichen) ist die Netzpostadresse von Stefan Ram.   |   Eine Verbindung zur Stefan-Ram-Startseite befindet sich oben auf dieser Seite hinter dem Text "Stefan Ram".)  |   Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram. Schlüsselwörter zu dieser Seite/relevant keywords describing this page: Stefan Ram Berlin slrprd slrprd stefanramberlin spellched stefanram722684 stefan_ram:722684 Nichtinitialisierung in C++ Stefan Ram, Berlin, and, or, near, uni, online, slrprd, slrprdqxx, slrprddoc, slrprd722684, slrprddef722684, PbclevtugFgrsnaEnz Erklärung, Beschreibung, Info, Information, Hinweis,

Der Urheber dieses Textes ist Stefan Ram. Alle Rechte sind vorbehalten. Diese Seite ist eine Veröffentlichung von Stefan Ram.
https://www.purl.org/stefan_ram/pub/nichtinitialisierung_c++