2015-10-14 13 views
10

Dies ist eine sehr einfache Frage:Globale Variable 0 initialisiert Strafe

Does 0-Initialisierung globale und statische Variablen jede Leistungseinbuße haben (wenn auch sehr klein) zur Laufzeit?

+1

Normalerweise werden die Variablen mit statischer Speicherdauer in den '.DATA'-Block Ihrer ausführbaren Datei geschrieben und zur Codegenerierungszeit auf Null gesetzt. Daher lautet die Antwort nach bestem Wissen "Nein". Tatsächlich denke ich historisch, dass dies der Grund ist, warum Variablen mit statischer Speicherdauer Null initialisiert werden - weil sie keine Strafe haben. – Rostislav

+0

@Rostislav Bedeutet das, dass der Loader etwas wie 'memcpy (loading_address, address_of_data_section_with_zeroes, size_of_data_section)' ausführt? – Dean

+0

@Rostislav, im Allgemeinen, Sie sind falsch, da Sie einen sehr wichtigen Punkt fehlt - Standard-Initialisierung von Nicht-Pods. – SergeyA

Antwort

11

Nein, da der C++ (und C) Standard besagt, dass alle globalen/statischen Variablen, die nicht explizit vom Programmierer initialisiert werden, auf Null initialisiert werden müssen. Solche Variablen werden in einem speziellen Segment namens .bss platziert. Sie werden vor dem Aufruf von main() auf Null initialisiert.

Wenn Sie Ihre globale/statische explizit, aber auf den Wert 0 initialisieren, ist der Compiler intelligent genug, dies zu realisieren und es immer noch in das Segment bss zu setzen.


Sie können dies testen für sich selbst mit einem Beispiel wie folgt aus:

#include <stdio.h> 

static int uninit; 
static int init_zero=0; 
static int init_one=1; 

int main (void) 
{ 
    printf("%p\n", &uninit); 
    printf("%p\n", &init_zero); 
    printf("%p\n", &init_one); 

    return 0; 
} 

In diesem Beispiel sind die uninit und init_zero Variablen werden bis an benachbarten Speicheradressen (wahrscheinlich 4 Bytes voneinander entfernt Ende), da sie beide im .bss Segment sind. Aber die init_one Variable wird woanders vollständig enden, weil es im .data Segment zugeordnet ist.

+2

Der Standard sagt, dass sie null-initialisiert werden müssen, aber ich bezweifle, dass es irgendetwas über '.bss' Segment gibt. Also könnte _ eine Architektur sein, in der Null-Initialisierung zur Laufzeit durchgeführt wird - ist das korrekt? – Rostislav

+0

@Rostislav Obwohl der Standard es nicht erwähnt, ist ".bss" traditionell der Name dieses Segments auf fast jeder Plattform, von 8-Bit-Mikrocontrollern bis zu 64-Bit-PC. In der Praxis macht das praktisch jede Anwendung zur Laufzeit.Sogar auf einem RAM-basierten System wie einem PC wird immer Code ausgeführt, bevor das Programm gestartet wird. Auf einem ROM-basierten System, wie einem Mikrocontroller, hat das Programm keine andere Wahl, als das sogenannte "Zero-Out" in der Laufzeit durchzuführen. – Lundin

+0

[Diese Antwort] (http://stackoverflow.com/questions/9535250/why-is-the-bss-segment-required/9535579#9535579) gibt ein Beispiel. – Lundin

-2

Erweitern Sie die Frage von 0-Initialisierung (die nur eine Teilmenge von) zu Standardinitialisierung ist, können wir immer noch feststellen, dass es normalerweise keinen messbaren Einfluss auf die Anwendungsleistung hat. Es ist jedoch leicht, eine Klasse zu entwerfen, die beispielsweise im Konstruktor Datenbanksuchen durchführt - was zu interessanten Effekten führt, die während des Anwendungsstarts bemerkbar sind.