Chyba: X může být použit neinicializované v této funkci v C

hlasů
1

Jsem dostat tuto chybu

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

A to je můj kód:

 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 kód je takhle, protože chci, aby volání funkce provádění pouze poprvé. V každém říkají Access proměnná bude aktualizován tak, že nedává mnoho smyslu, aby bylo statické.

Když udělám Access statické práce, ale nemám rád, aby to statické protože každý druhý hovor Přístup se bude aktualizovat. Nějaký způsob, jak se problému vyhnout, aniž by to statické ?.

Také nějaké lepší možnosti provést pouze jednou funkcí namísto použití statické proměnné jsou vítány.

Díky moc předem.

Položena 10/03/2009 v 00:20
zdroj uživatelem
V jiných jazycích...                            


4 odpovědí

hlasů
6

Dělat Accesstakhle (a odstranit FirstTimea if):

static MyStruct Access = Implementation(this_b);

Důvod, proč se dostanete toto varování proto, že statické proměnné přežít jedno volání funkce. Jejich hodnota je zachována u všech volání funkce ( bez ohledu na který nit hovorů, které funkce). Takže, FirstTimebude kontrolovat, zda se inicializovat Access. Při prvním volání funkce, která je kód bude správně inicializovat Accessproměnné. Ale s každým dalším volání funkce, FirstTimeje nulová, a budete není inicializovat Accessanymore, a tak budou používat neinicializované proměnné dolů kódu.

Edit: A teď, s aktualizovanými údaji, říkáte, že máte dvě Implementationfunkce. Poprvé, když budete chtít použít jeden, a všechny ostatní doby, kdy chcete použít jinou funkci. Jak se o tom pak:

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

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

V závislosti na konkrétním případě použití, může být lepší způsoby, jak řešit tento problém, ačkoli. Například, proč nelze aktualizovat stav Access, jako je tento:

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

Něco takhle MyUpdater:

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

Že vzor se nazývá RAII: Můžete spojit několik užitečných akci s konstruktérem a destruktor lokálně přidělené objektu.

Odpovězeno 10/03/2009 v 00:28
zdroj uživatelem

hlasů
2

@ Odpověď litb je zajímavé. Ekvivalentní program následujícím způsobem. Kód je sestaven a pracuje, jak je uvedeno v jazyce C ++, ale není sestavit v 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 říká:

xc: Ve funkci 'inc': xc: 7: Chyba: Inicializátor prvek není konstantní

g ++ je docela spokojený s tím.

To je rozdíl mezi C a C ++, že jsem si nebyl vědom (ale to by se nevejdou do 300 znaků, takže nemohu dělat to komentovat, snadno).


@Eduardo zeptal na jednu z otázek v připomínkách: „Proč C nepřipustí a C ++ dovolí?“. Vzhledem k tomu, že odpověď je více než 300 znaků ...

Jak @litb řekl v komentářích, v jazyce C můžete použít pouze konstanty pro Inicializátory statických proměnných. To je částečně proto, že hodnoty jsou nastaveny před main () se nazývá, a žádné uživatelem definované funkce se nazývají před main () je volána. C ++, naopak umožní globální a statické proměnné, které mají být iniciovány (uživatelem definované) konstruktéry před main () se nazývá, takže není žádný důvod, proč nedovolit další uživatelsky definované funkce, které mají být nazýván taky, takže inicializace je rozumné. S C89, jste omezeni v Inicializátory lze použít s automatickým (místní) proměnných; v C99, můžete použít skoro žádný výraz inicializovat libovolné lokální proměnné.

Odpovězeno 10/03/2009 v 00:45
zdroj uživatelem

hlasů
1

Access není statická a proto musí být vytvořeny v každém hovoru.

Zvážit zjednodušení kódu na něco jako:

static MyStruct Access = Implementation(this_b);

Tím je zajištěno, že funkce bude volána pouze při prvním metoda je spuštěn a že Accessbude mít hodnotu mezi hovory.

Odpovězeno 10/03/2009 v 00:30
zdroj uživatelem

hlasů
1

Přístup není statický, proto je vytvořena nová instance pokaždé funkce se nazývá. Pouze na poprvé přes vy vlastně přiřadit libovolnou hodnotu k němu; Tato hodnota je ztracen, jakmile funkčních východy.

Pokud potřebujete přístup k přetrvávat přes volání do funkce, aby byl statický.

Odpovězeno 10/03/2009 v 00:27
zdroj uživatelem

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