Automatische Initialisierung von Variablen unter C++/CLI ??



  • Ich habe folgendes kleine Programm geschrieben:

    #include "stdafx.h"
    using namespace System;
    using namespace System::IO;
    /* Das Programm erstellt ein "Histogramm" der Dateigrößen
    von Bilddateien.
    Es werden alle Dateien, die mit DSCF... anfangen 
    unterhalb von users\pictures gefunden.
    */
    
    long long kb1,kb2,kb3,kb4,kb5,kb6,kb7,kb8,kb9;
    
    String^ ExtractFilename(String^ s) {
      return(s->Substring(s->LastIndexOf("\\")+1));
    }
    
    void ParseDir(String^ dir) {
      array<String^>^ liste=Directory::GetDirectories(dir);
      for each(String^ s in liste) ParseDir(s);
      liste=Directory::GetFiles(dir);
      long long summe=0;
      for each(String^ s in liste) {
         String^ zwstring=ExtractFilename(s);
         if (zwstring->Substring(0,4)=="DSCF")
         {
           FileInfo^ datei=gcnew FileInfo(s);
           long long kb=datei->Length/1024;
           if(kb==0 && datei->Length>0) kb=1;
           if (kb<1000) kb1++;
           if (kb>=1000 && kb<2000) kb2++;
           if (kb>=2000 && kb<3000) kb3++;
           if (kb>=3000 && kb<4000) kb4++;
           if (kb>=4000 && kb<5000) kb5++;
           if (kb>=5000 && kb<6000) kb6++;
           if (kb>=6000 && kb<7000) kb7++;
           if (kb>=7000 && kb<8000) kb8++;
           if (kb>=8000 && kb<9000) kb9++;
        }
      }
    }
    
    int main(array<System::String ^> ^args)
    {
      String^ dir="c:\\users\\nutzer\\pictures";
      ParseDir(dir);
      Console::WriteLine("kleiner  1000:          {0}", kb1);
      Console::WriteLine("zwischen 1000 und 2000: {0}", kb2);
      Console::WriteLine("zwischen 2000 und 3000: {0}", kb3);
      Console::WriteLine("zwischen 3000 und 4000: {0}", kb4);
      Console::WriteLine("zwischen 4000 und 5000: {0}", kb5);
      Console::WriteLine("zwischen 5000 und 6000: {0}", kb6);
      Console::WriteLine("zwischen 6000 und 7000: {0}", kb7);
      Console::WriteLine("zwischen 7000 und 8000: {0}", kb8);
      Console::WriteLine("zwischen 8000 und 9000: {0}", kb9);
    }
    

    Meine Frage: werden die Variablen kb1 bis kb9 unter C++/CLI automatisch mit Null initialisiert? Ich habe vergessen, sie zu initialisieren, aber es kommt das richtige Ergebnis raus. Ich verwende Visual c++ 2008 Express Edition.
    Vielen Dank!



  • Deine Variablen vom Typ "long long" sind normale C++ variablen, d.h. "unmanaged".

    In C/C++ werden globale Variablen standardmäßig auf NULL initialisiert, wenn kein Initialisierungswert explizit angegeben ist. Das sollte in C++/CLI nicht anders sein, da es sich ja um eine Übermenge von C++ handelt.

    Übrigens, wieso nicht einfach:

    long long g_kb[10];
    
    void ParseDir(String^ dir)
    {
      array<String^>^ liste=Directory::GetDirectories(dir);
      for each(String^ s in liste) ParseDir(s);
      liste=Directory::GetFiles(dir);
      for each(String^ s in liste)
      {
         String^ zwstring=ExtractFilename(s);
         if (zwstring->Substring(0,4)=="DSCF")
         {
           FileInfo^ datei=gcnew FileInfo(s);
           size_t index = (size_t)(datei->Length / 1024 / 1000);
           if(index > 9) index = 9;
           g_kb[index]++;
        }
      }
    }
    


  • Ich verfolge die Entwicklung des C++ Standards nicht aktiv. Aber normalerweise werden Variablen in C/C++ grundsätzlich nicht initialisiert.
    Häufig wird dies durch den Debugger erledigt. Das hat auch bei mir schon zu allerlei frustrierender Fehlersuche geführt. Aber irgendwann lernt man's dann doch.

    Bei globalen Variablen mag eine Initialisierung beim Startup noch unproblematisch sein,da man das im Startup-Code abwickeln kann. Aber alles was aufm Stack angelegt wird, wird dann zu einem Geschwindigkeitsproblem.

    Vorallem ist eine Initialisierung mit 0 ja nur einer von vielen möglichen Werten die eine Variable annehmen kann. Man würde also einen Wert benutzen der in vielen Fällen doch wieder überschrieben wird.

    Bin mir sicher. Keine Initialisierung von Variablen in C/C++.



  • simbad schrieb:

    Aber normalerweise werden Variablen in C/C++ grundsätzlich nicht initialisiert.

    Das stimmt so nicht ganz 😉

    Da hast recht, dass lokale (Stack) Variablen sowie Speicher, den Du auf dem Heap allozierst (mittels "malloc" or "new"), normalerweise nicht initialisiert werden. Der Debugger (bzw. im Debug-Mode kompilierter Code) mag es trotzdem tun.

    Anders ist das jedoch bei globalen Variablen! Oder genauer: bei Variablen die "static storage duration" haben. Diese werden in C/C++ auf NULL initialisiert, und zwar immer! Üblicherweise passiert das beim Laden des Programms mittels .bss Sektion.

    Siehe:
    http://en.cppreference.com/w/cpp/language/zero_initialization

    `Zero initialization is performed in the following situations:

    1. For every named variable with static or thread-local storage duration, before any other initialization.

    [...]`

    In C, statically-allocated objects without an explicit initializer are initialized to zero (for arithmetic types) or a null pointer (for pointer types). Implementations of C typically represent zero values and null pointer values using a bit pattern consisting solely of zero-valued bits (though this is not required by the C standard). Hence, the BSDD section typically includes all uninitialized variables declared at file scope (i.e., outside of any function) as well as uninitialized local variables declared with the "static" keyword.

    Hier ist noch zu beachten, was alles unter Variablen mit "static storage duration" fällt:
    http://www.informit.com/guides/content.aspx?g=cplusplus&seqNum=30

    Global objects and objects in a namespace scope, static data members of a class, and local static objects in functions reside static storage duration. An object with static storage duration resides in the same memory address throughout the program's execution. Every such object is constructed only once during the lifetime of the program. By default, static data is initialized to binary zeros. global variables have static storage.

    Globale Variablen haben also auch dann "static storage duration", wenn sie nicht explizit als static definiert sind. Das Schlüsselwort static beeinflusst bei einer globalen Variable (außerhalb einer Funktion definiert) nämlich nicht etwa die "storage duration" (wie man meinen könnte) sondern das "linkage" der Variable ("internal linkage" vs. "external linkage"). Egal ob vor der globalen Variable static steht oder nicht, sie hat also "static storage duration" und wird daher mit NULL-Bytes initialisiert.



  • Fein fein. Nun weiß ich es ganz genau 😉


Anmelden zum Antworten