Globale Variable in C



  • linux_c89 schrieb:

    Wenn ich beispielsweise Bilddaten verarbeite, sagen mir x und y schon mal, dass wohl Zeilen- und Spaltenindizes gemeint sind

    Ich denke i,j,k haben sich soweit durchgesetzt das sie sehr aussagekräftig sind
    Wenn ich i sehe weiß ich "ah das ist die Zählvariable der äußersten Schleife"

    Na ja, ich kann aber y viel leichter mit dem Spaltenindex assoziieren als i. Versteh mich nicht falsch, ich spreche nur von diesem Beispiel (Bilddaten). Ansonsten nehme ich auch i,j,k oder gleich was Deutlicheres. Möglich wären ja noch etwas sprechendere Bezeichner wie z.B. row und col...



  • Danke für euere Antworten.

    Zunächst etwas zur Klärung:
    Ich verstehe unter "globalen Variablen" Variable, die im Gültigkeitsbereich eines Moduls sind. Linke ich weitere Module hinzu übergebe ich an diese einen klar definierten Storagebereich (analog einem Funktionsaufruf in C), Dieses dazugelinkte Modul benutzt dann den selben klar definierten Speicher wie der Caller. Ich gehe ebenfalls davon aus, dass der selbe Prozess mehrmals aufgerufen einen klar definierten eigenen Storage haben. In der IBM Mainframe Welt - und nur da kann ich mitreden - gibt es für solche mehrfach laufenden Prozesse resp Programme (der Code eines solchen Programmes ist dann nur einmal im Speicher und der Datenbereich wird entsprechend gehandhabt, so dass analog dem BS der selbe Code mehrfach genutzt werden kann) spezielle Programmiertechniken. Stichwort reentrant und reusability.

    Wenn ich aber solche spezielle Anforderungen nicht habe - etwa bei einer lokalen Desktopapplikation mit gemeinsam genutzter DB uber ein Netz - kann ich mir doch solche Dinge Sparen wie
    @pferdefreund schrieb:

    Sicherlich machen Schleifenzähler, Schalter usw lokal richtig Sinn aber je nach Toolkit für grafische Oberflächen machen aber auch globale Variablen Sinn und ersparen das am Anfang genannte massenweise Übergeben von parametern, Strukturen usw. Wenn z. B die Eingabefelder einer Maske dann auch noch schön sprechend benannt sind (Pferdename, Pferderasse..), dann spricht für mich - und ich entwickle seit 1982, nix dagegen, globale Variablen zu verwenden, sei es nun C, Abap, oder was auch imme.

    Das ist genau genommen die Aussage auf die ich hinauswollte und die Intention meines Eröffnungsposts.
    @SaHel schrieb:

    Also: was macht es für einen Sinn, auf globale Variable (ausser etwa technische Schleifen- oder sonst temp. -Felder) möglichst zu verzichten?

    @_matze

    Memory allocation issues -- Some environments have memory allocation schemes that make allocation of globals tricky. This is especially true in languages where "constructors" have side-effects other than allocation (because, in that case, you can express unsafe situations where two globals mutually depend on one another). Also, when dynamically linking modules, it can be unclear whether different libraries have their own instances of globals or whether the globals are shared.

    Wenn das in manchen Umgebungen so ist (welche?), wäre das natürlich eine Antwort.

    Meine obige Klärung von "globalen Variablen" erläutert auch den Einwand von @mngbd

    Bitte ein wenig konkreter machen, sonst wird das eine Wischiwaschi-Diskussion mit abstrakten Argumenten wie "lokal ist der Zugriff tendenziell schneller" oder "weniger global ist übersichtlicher".
    🙂

    Und nocheinmal es ging um eine Frage und nicht um einen Religionskrieg. CICS und IMS sind nun mal nicht Windows oder Linux.



  • SaHel schrieb:

    Ich verstehe unter "globalen Variablen" Variable, die im Gültigkeitsbereich eines Moduls sind.

    Schon der erste Irrtum. Mittels "extern" kann jedes andere Modul auf deine "modulglobalen" Variablen zugreifen, auch schreibend, d.h. sie sind programmglobal. Deshalb macht man sie mittels <static> zu wirklich modulglobal.



  • Wutz schrieb:

    Schon der erste Irrtum. Mittels "extern" kann jedes andere Modul auf deine "modulglobalen" Variablen zugreifen, auch schreibend, d.h. sie sind programmglobal. Deshalb macht man sie mittels <static> zu wirklich modulglobal.

    extern?? automatisch?? Ich verstehe langsam das C (oder muss ich sagen Unix, Linux, Windows??) Prinzip
    Gefunden unter http://wiki.answers.com/Q/What_is_the_use_of_extern_in_C

    The "extern" declaration in C is to indicate the existence of, and the type of, a global variable or function. A global variable, or a global function, is one that is available to all C modules (a single C module is typically a single .c file). An extern is something that is defined externally to the current module. In many cases, you can leave off the extern qualifier and not notice any difference because the linker can collapse multiple definitions to one. But the intent is then unclear in the code, and the code is error prone in case of typos. It is much clearer to define the global in one place, and then declare extern references to it in all the other places. When refering to globals provided by a library, especially a shared library, this is even more important in order to ensure you are talking about the correct, common instance of the variable.

    Aber so etwas ist ja schrecklich... historisch? konzeptionell?? oder gibt es da einen besonderen Grund? Was für Vorteile hat das?
    Ich meine diese Aussage:

    In many cases, you can leave off the extern qualifier and not notice any difference because the linker can collapse multiple definitions to one. But the intent is then unclear in the code, and the code is error prone in case of typos



  • SaHel schrieb:

    Aber so etwas ist ja schrecklich... historisch? konzeptionell?? oder gibt es da einen besonderen Grund? Was für Vorteile hat das?
    Ich meine diese Aussage:
    ...

    Manchmal teilt man die Typ-Vereinbarungen auf in Definitionen, die Speicherplatz bereitstellen, und Deklarationen, die nur den Typ eines Namens vereinbaren. In diesem Sinn ist die Aussage falsch, weil mehrere gleichzeitig sichtbare Definitionen des gleichen Namens ein Fehler sind. Aber viele Deklarationen, z.B. von Funktionen, erkennt der Compiler auch ohne das 'extern', und wenn er die Definition nicht im betreffenden Modul findet, muss sie eben woanders sein. In solchen Fällen darf man das 'extern' weglassen.

    Zum Beispiel zwei Dateien:

    #include <stdio.h>
    
    /* Definition des Zeigers mit Ziel */
    char *global = "global";
    
    /* Definition der Funktion */
    void function(void) { puts(global); }
    
    #include <stdio.h>
    
    /* Deklaration des Zeigers */
    extern char *global;
    /* Deklaration der Funktion, 'extern' kann man weglassen */
    extern void function(void);
    
    /* Definition von main() */
    int main(void)
    {
        puts(global);
        global = "changed";
        function();
        return 0;
    }
    

    🙂



  • mngbd schrieb:

    Manchmal teilt man die Typ-Vereinbarungen auf in Definitionen, die Speicherplatz bereitstellen, und Deklarationen, die nur den Typ eines Namens vereinbaren. In diesem Sinn ist die Aussage falsch, weil mehrere gleichzeitig sichtbare Definitionen des gleichen Namens ein Fehler sind. Aber viele Deklarationen, z.B. von Funktionen, erkennt der Compiler auch ohne das 'extern', und wenn er die Definition nicht im betreffenden Modul findet, muss sie eben woanders sein. In solchen Fällen darf man das 'extern' weglassen.

    Wenn ich das jetzt richtig verstanden habe, besteht bei diesen globalen Variablen die Gefahr, dass sie vom Compiler als extern interpretiert werden können - etwa bei Namensgleichheit und fehlender Dekleration in einem anderen Modul.

    In der von mir eingangs beschriebenen "EDV Welt" gibt es so etwas so explizit nicht. Dort werden zwischen verschiedenen Modulen lediglich Anfangsadressen übergeben - und zwar vom Caller (ähnlich eines Funktionsaufrufs in C innerhalb eines Moduls). Damit der Called mit dieser Adresse etwas anfangen kann arbeitet man dort mit sogenannten "Copybooks". Das sieht dann stark vereinfacht etwa so aus:

    Prog1
    [...]
    copy "kdstamm".
    (Felder von kdstamm werden beim Compile hier eingefügt)
      kdnr int
      kdname char[xx] (aber anderer Syntax als in C)
    [...]
    Und im Code dann:
    CALL "PROG2" USING kdstamm. (Adresse von kdstamm wird übergeben)
    [...]
    

    In Prog2 wird dann dem Compiler gesagt, dass es sich nicht um eigenen Storage handelt:

    Prog2
    [...]
    Spezieller Linkbereich
    copy "kdstamm".
    (Felder von kdstamm werden beim Compile hier ebenfalls eingefügt)
      kdnr int
      kdname char[xx]
    [...]
    
    Un beim Start (Code) wird dem Compiler dann via USING kdstamm mitgeteilt, 
    dass bei diesem kdstamm die übergebene Adresse vom Caller stammt (*kdstamm aus
     Prog1). Die Namensgebung ist dabei egal (analog C).
    
    [...]
    Macht irgendwas mit kdnr, kdname....
    [...]
    

    Mit dieser Technik verwaltet immer der Caller den gemeinsamen Speicher für den Called. Und die ganze Sache ist transparent.
    Nun ja - andere Welten andere Sitten 😉
    Besten Dank für eure Antworten, die Frage ist damit beantwortet....



  • SaHel schrieb:

    Wenn ich das jetzt richtig verstanden habe, besteht bei diesen globalen Variablen die Gefahr, dass sie vom Compiler als extern interpretiert werden können - etwa bei Namensgleichheit und fehlender Dekleration in einem anderen Modul.

    Die Gefahr besteht, Beispieldateien:

    char *global = "one";
    char *function(void) { return global; }
    
    #include <stdio.h>
    
    extern char *function(void);
    char *global;
    
    int main(void)
    {
        global = "two";
        puts(global);
        puts(function());
        return 0;
    }
    

    global ist hier eine über beide Dateien ("compilation units") globale Variable. Man könnte erwarten, dass die beiden Variablen verschieden sind, weil es so aussieht, als würde in beiden Dateien Speicher für sie bereitgestellt; aber eben das ist nicht der Fall. Wenn man dabei ein Missverständnis befürchtet, sollte man in der zweiten Datei global entweder initialisieren (das ergibt hier einen Fehler beim Linken, wegen der Mehrfach-Definition) oder das extern dazuschreiben (dann ist klar, dass es nicht als Definition verstanden werden soll).

    Das erklärt teilweise, warum erfahrene C-Leute dazu tendieren, alle Variablen zu initialisieren. Es empfiehlt sich in diesem Sinn auch, das extern niemals wegzulassen.

    Falls aber zwei verschiedene, nur über die jeweilige Datei globale Variablen erwünscht sind, muss man sie, wie gesagt, static machen. Weil das der Regelfall ist, kann man sagen, dass es ein Fehler von C ist, globale Variablen per default global über alle Dateien zu machen.

    Warum ist das so? Ich kann mir vorstellen, dass es daran liegt, dass C als möglichst einfache Sprache gedacht ist, und man auf diese Weise solche Fragen des Linkens weitgehend aus der Syntax heraushalten kann, was den Compiler einfach und portabel hält.
    🙂



  • mngbd, wieso machst Du unter fast jeden Beitrag einen Smiley? 😕



  • Um frickys Andenken zu wahren? 😃



  • _matze schrieb:

    Um frickys Andenken zu wahren?

    Wer ist das?



  • Fragensteller2 schrieb:

    mngbd, wieso machst Du unter fast jeden Beitrag einen Smiley? 😕

    Schade...
    Ich bin gerade ein wenig am Testen, um das Linkverhalten von diesen glob. Variablen besser beurteilen zu können. Habe aber wenig Zeit. Wer weiss, vielleicht hilft dem einen oder anderen C Umsteiger ein solcher Thread. 😉

    Ach ja, das war gerade auch ein Smiley

    SaHel



  • SaHel schrieb:

    Habe aber wenig Zeit. Wer weiss, vielleicht hilft dem einen oder anderen C Umsteiger ein solcher Thread.

    Du musst ja nicht alles lesen, wir würden auch ganz ohne Publikum über C philosophieren.

    Fragensteller2 schrieb:

    mngbd, wieso machst Du unter fast jeden Beitrag einen Smiley? 😕

    Weil ich ihn manchmal vergesse.

    _matze schrieb:

    Um frickys Andenken zu wahren? 😃

    Wer ist denn das? Ich hab das von dem/der übernommen:
    http://www.c-plusplus.net/forum/profile-var-mode-is-viewprofile-and-u-is-106530.html
    🙂



  • (versehentlich zweimal gepostet)



  • mngbd schrieb:

    http://www.c-plusplus.net/forum/profile-var-mode-is-viewprofile-and-u-is-106530.html
    🙂

    😮 was?? 935361 Beiträge und das seit 20.09.2007? 54% aller Beitrage stammen von ihm/ihr? Ist das nicht ein DB Fehler?



  • supertux schrieb:

    😮 was?? 935361 Beiträge und das seit 20.09.2007? 54% aller Beitrage stammen von ihm/ihr? Ist das nicht ein DB Fehler?

    Admin fragen. Oder gut suchen.
    🙂



  • mngbd schrieb:

    Wer ist denn das? Ich hab das von dem/der übernommen:

    you never walk alone ...
    🙂


Anmelden zum Antworten