Frage

Ich erhalte diese Fehler

error: Access.Core may be used uninitialized in this function

Und das ist mein Code:

 static int FirstTime = 1;
 MyStruct Access;

 if (FirstTime) {
   FirstTime = 0;
   Access = Implementation();
   DoSomething(Access);
 }

 if(Other_Variable) {
    Access = Implementation2();
    DoSomething(Access);
  }

  //The Other_Variable will be set to 1 and to 0 by other part of the code

Mein Code ist so, weil ich nur das erste Mal auf die Funktion Implementierung anrufen möge. In jedem Anruf des Access-Variable aktualisiert werden wird, so dass es sie statisch nicht viele sinnvoll machen.

Wenn ich Zugang statische Arbeiten machen, aber ich weiß nicht, wie es statisch machen, weil in jedem anderen Call-Zugang wird aktualisiert werden. Jede Art und Weise, das Problem zu vermeiden, ohne dass es statisch?.

Auch keine besseren Optionen nur einmal eine Funktion stattdessen auszuführen von einer statischen Variable sind willkommen.

War es hilfreich?

Lösung

Machen Sie Access wie diese (und entfernen FirstTime und die if):

static MyStruct Access = Implementation(this_b);

Der Grund, warum Sie diese Warnung erhalten, weil statische Variablen einen Funktionsaufruf zu überleben. Ihr Wert wird über alle Funktionsaufrufe beibehalten ( ohne Hinweis auf den Thread, die Funktionsaufrufe). So wird FirstTime steuern, ob Sie Access initialisieren. Das erste Mal, rufen Sie die Funktion, den Code in ist korrekt den Access Variable initialisieren. Aber mit jedem weiteren Funktionsaufruf ist FirstTime Null, und Sie werden nicht initialisieren Access mehr, und somit wird eine nicht initialisierte Variable auf den Code verwenden.

Edit: Jetzt, mit Ihren aktualisierten Daten, Sie sagen, dass Sie zwei Implementation Funktionen haben. Das erste Mal, wenn Sie eine verwenden möchten, und alle anderen Zeiten wollen Sie eine andere Funktion verwenden. Wie wäre es damit dann:

 // static will be false/zero by default
 static bool AlreadyCalled;
 MyStruct Access;

 if (!AlreadyCalled) {
   Access = Implementation();
   AlreadyCalled = true;
 } else {
   Access = Implementation2();
 }

Je nach tatsächlichen Anwendungsfall kann es bessere Möglichkeiten, dies zu umgehen, though. Zum Beispiel, warum sich nicht um den Zustand von Access, wie folgt aus:

// let the default constructor initialize it
// to a plausible state
static MyStruct Access;

// use RAII to update the state of Access when this
// function returns. 
MyUpdater updater(Access);

// now, do whatever the function does. 

So etwas wie dies für MyUpdater:

struct MyUpdater {
    MyStruct &s;
    MyUpdater(MyStruct &s):s(s) { }
    ~MyUpdater() {
        s.ChangeState();
    }
};

Dieses Muster RAII genannt wird: Sie ordnen einige nützliche Aktion mit dem Konstruktor und Destruktor eines lokal zugeordneten Objekts.

Andere Tipps

@ litb Antwort ist interessant. Ein äquivalentes Programm folgt. Der Code kompiliert und arbeitet wie in C ++ angegeben, aber nicht kompiliert in C.

#include <stdio.h>

static int newval(void) { return 3; }

void inc(void)
{
    static int a = newval();

    a++;
    printf("%d\n", a);
}

int main(void)
{
    int i;
    for (i = 0; i < 10; i++)
        inc();
    return(0);
}

gcc sagt:

x.c: In der Funktion 'inc': x.c: 7: Fehler: initializer Element nicht konstant ist

g ++ ist ganz zufrieden damit.

Das ist ein Unterschied zwischen C und C ++, die mir nicht bewusst war (dies würde aber nicht in 300 Zeichen passen, so kann ich es nicht ein Kommentar, leicht).


@Eduardo fragte eine der Fragen in den Kommentaren: „Warum C diese und C nicht zulassen, dass ++ es zulassen?“. Da die Antwort ist mehr als 300 Zeichen ...

Wie @litb in den Kommentaren gesagt, in C können Sie nur Konstanten für initializers von statischen Variablen verwenden. Dies ist zum Teil, weil die Werte eingestellt werden, bevor main () aufgerufen wird, und es wird keine benutzerdefinierten Funktionen aufgerufen werden, bevor main () aufgerufen wird. C ++, dagegen ermöglicht globale und statische Variablen (benutzerdefiniert) Konstrukteurs initialisiert werden, bevor main () aufgerufen wird, so gibt es keinen Grund, nicht andere benutzerdefinierte Funktionen zu ermöglichen, auch genannt werden, so dass die Initialisierung ist vernünftig. Mit C89, sind Sie in dem initializers begrenzt Sie mit automatischen (lokalen) Variablen verwenden können; in C99, können Sie so ziemlich jeden Ausdruck verwenden, jeden lokalen Variable zu initialisieren.

Der Zugang ist nicht statisch, daher wird eine neue Instanz erstellt wird jedes Mal die Funktion aufgerufen wird. Nur auf der ersten Zeit zu tun, durch die Sie tatsächlich jeden Wert zuweisen; dieser Wert wird, sobald die Funktion beendet verloren.

Wenn Sie Access müssen über Aufrufe an die Funktion bestehen, machen es zu statisch.

Access ist nicht statisch und deshalb muss es in jedem Aufruf erstellt werden.

Betrachten Sie den Code, um etwas zu vereinfachen, wie:

static MyStruct Access = Implementation(this_b);

Damit wird sichergestellt, dass die Funktion nur das erste Mal aufgerufen werden, wobei das Verfahren ausgeführt wird, und dass Access den Wert zwischen Anrufen halten.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top