Błąd X mogą być stosowane w tej funkcji niezainicjowanego w C

głosy
1

Ja dostaję ten błąd

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

A to jest mój kod:

 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

Mój kod jest tak dlatego, że chcę zadzwonić do implementacją funkcji dopiero po raz pierwszy. W każdym zadzwonić zmienna dostęp ma być aktualizowany, więc nie zrobić wiele sensu sprawiają, że statyczne.

Jeśli zrobię dostępu prace statyczne, ale nie podoba mi się zrobić to statyczna, ponieważ w każdym innym wywołanie dostęp ma być aktualizowana. Każdy sposób, aby uniknąć problemu bez dokonywania to statyczne ?.

Także jakieś lepsze opcje, aby wykonać tylko raz funkcją zamiast przy użyciu zmiennej statycznej są mile widziane.

Z góry dziękuję.

Utwórz 09/03/2009 o 22:20
źródło użytkownik
W innych językach...                            


4 odpowiedzi

głosy
1

Dostęp nie jest statyczny, zatem nowa instancja jest tworzona za każdym wywołaniu funkcji. Tylko na po raz pierwszy przez czy rzeczywiście przypisać dowolną wartość do niego; Ta wartość jest stracone tak szybko wyjść funkcyjnych.

Aby uzyskać dostęp do całej utrzymują połączeń do funkcji sprawiają, że statyczne.

Odpowiedział 09/03/2009 o 22:27
źródło użytkownik

głosy
6

Zrobić Accesstak (i usunąć FirstTimea if):

static MyStruct Access = Implementation(this_b);

Powodem dostać to ostrzeżenie dlatego zmienne statyczne przeżyć jedno wywołanie funkcji. Ich wartość jest zachowana we wszystkich wywołań funkcji ( bez odniesieniu do których wątek wywołuje że funkcja). Tak, FirstTimebędzie kontrolować, czy zainicjować Access. Gdy pierwszy raz wywołać funkcję, która jest w kod zostanie poprawnie zainicjować Accesszmienną. Ale z każdym kolejnym wywołaniu funkcji, FirstTimejest zerem, a będziesz nie zainicjować Accessjuż, a więc będzie używać zmiennej niezainicjowanej dół kodu.

Edit: Teraz z aktualnych informacji, można powiedzieć, że masz dwie Implementationfunkcje. Gdy po raz pierwszy chcą skorzystać z jednej, a wszystkie inne czasy chcesz użyć innej funkcji. Jak o tym potem:

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

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

W zależności od rzeczywistego przypadku użycia, nie może być lepsze sposoby, aby sobie z tym poradzić, choć. Na przykład, dlaczego nie aktualizuje stanu Access, na przykład:

// 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. 

Coś takiego na MyUpdater:

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

Że wzór jest nazywany RAII: skojarzyć kilka użytecznych działań z konstruktora i destruktora lokalnie przydzielonego obiektu.

Odpowiedział 09/03/2009 o 22:28
źródło użytkownik

głosy
1

Access nie jest statyczna i dlatego musi być tworzone w każdej rozmowy.

Rozważyć uproszczenie kodu, aby coś takiego:

static MyStruct Access = Implementation(this_b);

Gwarantuje to, że funkcja zostanie wywołana tylko po raz pierwszy sposób jest prowadzony i że Accessbędzie posiadać wartość pomiędzy połączeniami.

Odpowiedział 09/03/2009 o 22:30
źródło użytkownik

głosy
2

@ Odpowiedź litb jest interesująca. Odpowiednikiem programu następuje. Kod kompiluje i działa jak podano w C ++, ale nie kompilacji w 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 mówi:

xc: W funkcji 'inc': xc: 7: error: Element Inicjator nie jest stała

g ++ jest bardzo z niego zadowolony.

To jest różnica między C i C ++, że nie byłem świadomy (ale to nie pasuje do 300 znaków, więc nie mogę zrobić to komentarz, łatwo).


@Eduardo poprosił jedno z pytań w komentarzach: „Dlaczego nie pozwalają na to C i C ++ to pozwolić?”. Ponieważ odpowiedź jest więcej niż 300 znaków ...

Jak @litb powiedział w komentarzach, w C można używać tylko dla stałych inicjalizatorów zmiennych statycznych. Jest to po części dlatego, że wartości są ustawione przed main () jest wywoływana i żadne funkcje zdefiniowane przez użytkownika są nazywane przed main () jest wywoływana. C ++, natomiast umożliwia zmienne globalne i statyczne być inicjowane przez konstruktorów (definiowane przez użytkownika) przed main () jest wywoływana, więc nie ma powodu, aby nie dopuścić inne funkcje zdefiniowane przez użytkownika, aby być nazywany też, więc inicjalizacja jest rozsądna. Z C89, jesteś ograniczony w inicjalizatorów można korzystać z automatycznych (lokalnych) zmiennych; w C99 można użyć prawie dowolne wyrażenie zainicjować żadnej zmiennej lokalnej.

Odpowiedział 09/03/2009 o 22:45
źródło użytkownik

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more