statikus változó törlése [MEGOLDVA]

Fórumok

A következő problémával kapcsolatban szeretnék segítséget kérni:

Nagyon leegyszerűsítve adott a következő szerkezet:


for(...){
   for(...){
     ...
     függvény(...);
     ...
   }
}

void függvény(...){
   ...
   static változó = 0;
   ...
}

Tehát, a függvényben van egy (vagy több) statikus változó, aminek az értékét csak addig szeretném megőrizni, amíg a belső ciklus fut. Amikor a belső ciklus végetér, és a külső ciklus lép egyet, azt szeretném, hogy a statikus változó kvázi újradeklarálódjon újradefiniálódjon, "resetelődjön".
Létezik erre valami egyszerű megoldás?

Hozzászólások

Például a belső ciklus után 0-ra állítod.

Szerintem globális változóval lehet csak megoldani.

Na ezaz ami nem megy.

Az a helyzet, hogy az egész dolog valójában sokkal bonyolultabb, legfelső szinten nagyjából így néz ki, ahogy a példában leírtam, de egyébként tele van még további, mélyebben lévő függvényekkel, azokban is statikus változókkal, statikus osztálypéldényokkal, stb., amiket mind törölni kellene.

Ha meg is csinálnám valahogy, akkor sem volna jó, mert a legfelül lévő függvénynek többé-kevésbé "önhordónak" kell lennie, egy dll-be lesz végül befordítva, és arra a környezetre, ahonnan meg lesz hívva, csak kevés befolyásom van.

Tehát kb. azt szeretném, hogy a függvényen belül lévő hierarchiában az összes statikus szar törlődjön, "gombnyomásra".

Ez így nem fog menni.
Vagy adsz a függvéynek egy int torold_a_statikus_valtozot paramétert, és a ciklusban ha kell, úgy hvod meg, hogy fuggveny(1), és akkor a függvény nem hajtja végre a dolgát, hanem törli a változókat.
De ez az egész elég ronda megoldás, írd újra szerintem.
Csináld meg úgy, hogy egy dinamikusan allokált struct -ot adsz át a függvénynek paraméterként, és ebben a struct -banvannak azok az adatok, amik kellenek.
Azt ehogyan sem fogod tudni elérni, hogy a függvényen kívül töröld annak a belső változóit, eleve nem látod a függvény belsejében levő névteret azon kívül, és ez nem holmi php meg egyebek, a c/cpp nem támogat ilyet, nincs erre megoldás.
Max hekkelni lehet, kitalálod valahogyan, hogy az adott architektúrán a memóriában hol tárolódnak a függvény lokális static változói, és azt a részt kinullázod.

De a függvényen kívülről kellene. Ezért nem triviális, legalábbis nekem.

A függvényen belül pedig azért nem jó, mert buta, nem tudja, mikor van vége a ciklusnak. Egyelőre a függvény megpiszkálása csak korlátozott opció. Pl. új paraméterátadást nem szeretnék belerakni.

Ha pointeresen csinálod, akkor úgy szép, hogy:

struct {
int valtozo1;
int valtozo2;
...
} MYDATA;

a függvényed:

void fuggveny(MYDATA* data) {
if(!data) return; /*ha NUL lett átadva, nem is próbálkozunk */

data->valtozo1 = ....;
}

adatokat tároló struct létrehozása ciklus elején:
MYDATA* data = (MYDATA*)malloc(sizeof(MYDATA))

ciklusban függvényhívás:
fuggveny(data);

ciklus vegen meg:
free(data);


void fuggveny(...,bool initit){
   ...
   static valtozo;
   ...
   if( initit ){ valtozo = 0; return ;}
}


//
for(...){
   fuggveny(...,true);
   for(...){
     ...
     fuggveny(...,false);
     ...
   }
}

ha a kodban nem tudod atirni a 'fuggveny' parszazezer elofordulasat, hogy a vegere biggyessz egy false erteket, akkor wrappelheto egy masik fuggvennyel vagy egy macroval, esetleg c++ -ban meg masik 200 egymastol fuggetlen megoldasa van a problemanak
----
szerk: most olvastam, hogy ne legyen uj parameter. akkor tekintsd targytalannak.

Én fejlesztem a függvényeket is, szóval elvileg lehetséges a váltotatás, ami akadályoz:

1. A végleges formájuk a mostani, tehát, ha magamnak össze is hekkelem valahogy a rendszert, az nem lesz jó a végleges változathoz, ha ez a függvények feltúrásával jár.

2. Sok meló. Végigmenni az összes szaron, mindenféle változók az egész függvényhierarchiában szanaszéjjel, olyan finomságokkal fűszerezve mint pl. statikus osztálypéldányok, ahol még maga a "reset" sem annyira egyértelmű, mint egy közönséges változónál (talán a destruktort kellene meghívni, aztán a kövekező ciklusban újra létrejönnek, vagy nem tudom), meg esetleg nézni azt, hogy közben mit barmolok széjjel azzal, hogy beletákolom egy kvázi "init" állapot lekezelését (ha így csinálnám), nem sok kedvem van hozzá.

ha sima C, akkor tobb piszkos (architecture-dependent) megoldas kepzelheto el

1) ha a fuggveny masik modulban van, akkor a static deklaracio egy irhato, masik memorialapra esik, compile-map segitsegevel megmondhato hova, azt fel tudod venni, tudod kivulrol manipulalni. (a c nem mas, mint egy gazos assembly) Ez persze kevesbe jo, ha az a modul zart forrasu, nem te forditod vagy valtozik, vagy olyan az architectura, hogy meg a static is befer egy regiszterbe.

2) ha external dynamic lib (.so) -ban van a fgvny, akkor dlclose();dlopen(); a kulso ciklusban.

3) kerjed a fuggveny fejlesztojetol a thread safe valtozatot:)

Nem sima C, hanem C++.

1) Egyelőre nem lenne probléma, de később lehet, hogy más architektúrán is kellene, hogy működjön, úgyhogy inkább nem ebbe az irányba mennék el (bár, akármennyire is mondják itt néhányan, hogy ez gányolás, szerintem szép, igazi hack :)

2) Ezen már én is gondolkodtam, de néha szükségem van néhány globális változóra, (amiket csak eseti jelleggel írok bele a kódba, de ettől még fontosak) és ha külső lib-ben van a függvény, akkor azthiszem buktam a globális változókat, de FIXME.

3) Én vagyok a függvény(ek) fejlesztője és nagyon úgy néz ki, hogy ilyesmit fogok kérni magamtól, ezzel csak az a baj, hogy sok, vagy legalábis ebből a szempontból bonyolult a kód, ráadásul konzisztens megoldás kellene, mert később, ahogy fejlődik tovább, újabb olyan feature-k kerülnek majd bele, amiknek kell static változó, és ezért jó lett volna olyan megoldást találni, ami a már meglévő és a csak ezután elkészülő függvényeknek is minimális módosításokkal megfelel. Arról nem is beszélve, hogy legalább 20-30 munkaórát meg tudnék spórolni, ha nem kellene az egész static koncepciómat felforgatni.

Ne haragudj, azt kell, hogy mondjam, hogy evvel a static koncepcióval el van baltázva az egész.
Amúgy arról nem volt szó, hogy C++ programot írsz.. ;)
Javaslatom:
A fuggveny() -t valtsd ki egy osztallya.
Gondolom ez a fuggveny szamol valamit.
Az osztalyodnak legyenek privat adattagjai, amiket a konstruktor inicializál.
A for ciklusok előtt létrehozod az osztályt, a végén törlöd.

+1

Most még a fejlesztés kezdeti szakaszában vagy, és máris hackelni készülsz. Ilyenkor automatikus kell legyen a refactoring.

Ha 2 év fejlesztés után valami apró új feature miatt kéne 3 hónapig dolgoznod még megérteném, de így...

Hidd el megéri. Ha az átalakítás jól sikerül, 2 nap múlva már azt veszed észre, hogy: "jééé, egy hete még mennyit szívtam ezzel a problémával, most meg 2 sor az egész".

Tisztább, szárazabb, biztonságosabb érzés...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Eh, ez könnyű pedig, főleg C++-ban, ahol lehet referenciákkal, és úgy transzparens.

int* _var() {
  static int i=0;
  return &i;
}
 
void func()
{
  static int* var=_var();
  ...
}

Bárhogy nézem a problémádat, csak az látszik, hogy újra kéne írnod az egészet.
Már az gyanús kell legyen ha c++-ban elkezdesz lokális statikus változókat használni. Én pl egy hirtelen felindulásból elkövetett debug kódon kívül sose használok ilyesmit.

Ökölszabály: ha egy függvény két futása között átmeneti adatokat kell tárolnod, akkor c++-ban gondolkozás nélkül osztályt kell írni. (A funktor is egy osztály.)
És lehetőleg osztályon belül is kerülni a statikus adattagokat...

Egyébként C-ben is ez a mutatós struct-os megoldás játszik. Nézz meg kb bármilyen C-s (akár dinamikus) lib-et. Szinte mindig van valami init fv, ami visszaad egy mutatót, amit aztán cipelned kell minden fv híváshoz.
(Miközben gyakran teljesen el van rejtve előled, hogy mire is mutat az a mutató.)

A statikus változó már csak azért sem jó, mert a legtöbb lib-nél el lehet képzelni olyat, hogy egy programon belül, de egymástól függetlenül kétszer is akarod használni, akár átfedésekkel. A statikus változók rögtön összekavarodnának...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Nos, a statikus változók nagyrésze valójában nálam sem statikus változó, hanem osztály van, és az osztálypéldányok statikusak (ez egyébként pont azért van így, amit írtál, hogy több példányban se kavarodjanak össze). De igazából ez mindegy, ebből a szempontból ugyanaz a probléma.

"a feladat jellegéből adódóan nem jó"
Amennyiben az a feladat, hogy hogyan tudod magad hibas tervezessel tokon szurni, arra a tobbiek altal vazolt eddigi javaslatok tenyleg nem nyujtanak megoldast :p Amit viszont nem ertek, ha mar egyszer ragaszkodsz az eddigi megoldashoz, akkor miert annyira problemas a fuggvenyednek egy "init" flaget atadni?

"Mert sok helyen kell és nem mindenhol oldható meg egyszerűen így."

Legyen default parameter, C++-ban lehet mar ilyet.
void fuggveny (bool toroljem_a_belso_static_szarjaimat = false) {

if (toroljem_a_belso_static_szarjaimat) {
// torlom oket
}

}

Fuggveny meghivasa, ahol torolni kell:

fuggveny(true);

Fuggveny meghivasa, ahol nem kell torolni a belso szarokat:

fuggveny();

Tehat ahol nem kell piszkalni, ott nem kell a kododban modositani a fuggenyhivast.

Keress a feladat jellegének megfelelő algoritmust, és akkor nem kell gányolni. Ha az algoritmus megtervezésénél alacsonyra tetted a mércét, akkor a programod minőségét is felülről korlátoztad.

-----
Nem vagyok gondolatolvasó, így nem tudom mit akartál írni. Ha nem szeretnéd, hogy félreértsenek, akkor fogalmazz pontosan.

"de a feladat jellegéből adódóan nem jó"

Ezt egyrészt nehezen hiszem, másrészt ha igaz, hogy ez ennyire speciális helyzet, akkor érdemes lenne többet elmondanod ebből a szupertitkos projectből, hogy segíteni tudjunk.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Naszóval:

http://en.wikipedia.org/wiki/Infinite_impulse_response

a problémát főleg az ilyen szűrők implementációja jelenti, főleg ha magasabbrendűekről van szó.

Ezek sok helyen szerepelnek a kódban (ráadásul több különöző változatban, ami változatonként eltérő számú statikus tagot feltételez), ezért készítettem egy szűrő-osztályt, amiből elég létrehozni egy új példányt, ha be akarok tenni egy újabb ilyen szűrőt. Mivel ezekre a legkülönbözőbb helyeken és kontextusban lehet szükség, ezért nem egyszerű csak úgy "kiszervezni" az állapotok kezelését a fő függvényemen kívülre, pl. elég ha csak azt nézzük, hogy egy új szűrő beépítése (vagy egy meglévő módosítása) ami egyáltalán nem ritka dolog, hány helyen implikálna változtatást.

Egyébként, lehet, hogy igazad van és el kellene kerülni a statikus változók vagy osztálypéldányok használatát, ez nyilván bevett pl. ha valami "userspace" dolgot csinálunk, de itt nem egészen ilyen feladatról van szó, a szűrők implementálása statikus változókkal teljesen industry-standard, szóval ezért sem szívesen változtatnék ezen (a fentebb részletezett dolgokon kívül).

szerk.:

a statikus változók használata ebben az esetben nem azért industry-standard, mert valaki egyszer a saját pillanatnyi szükségletei szerint vagy öntörvényűen kitalált valami hülyeséget és úgy maradt, hanem mert a szűrők működési elvéből adódik (ld. link), hogy meg kell őrizniük az állapotukat, ez pedig kézenfekvően statikus változókkal oldható meg.

> ...meg kell őrizniük az állapotukat, ez pedig kézenfekvően statikus változókkal oldható meg.

Igen, C-ben. C++-ban az osztály pont erre való. Privát adattagokat nyugodtan alkalmazhatsz a belső állapotváltozók reprezentálására, pont úgy viselkednek, ahogy neked kell.

--
Debian - The "What?!" starts not!
http://nyizsa.uni.cc

Igen, valószínűleg iylesmi lesz.

De nemcsak neked mondom, hanem a többieknek is, hogy nem azzal van a bajom, hogy nem tudom, hogy hogyan kell egy olyan megoldást készítenem mint ami pl. a te példádban le van írva, hanem, hogy nem ilyet szeretnék, hanem olyat, amilyet már korábban leírtam.

Más kérdés, hogy eddig úgy néz ki, hogy nem fog sikerülni.

Ertem en, nem is fikaztalak, segiteni probalok. :)
Viszont arra en is ra akarok vilagitani, hogy alapvetoen elhibazottan epitetted fel az eddigi programodat (az alapjan, amit tudunk rola).
Ha nincs sok 10 ezer programsorod, akkor erdemes ujrakezdeni, a megszerzett tapasztalatokat felhasznalva, hogy egy jo valami suljon ki belole. :)

"Viszont arra en is ra akarok vilagitani, hogy ... erdemes ujrakezdeni"

Na, ez már dereng :)

Egyébként tényleg nem egy programtervezési mestermű, de azt sem gondolnám, hogy alapjaiban elhibázott lenne, vagy, hogy magamat hibáztassam ezért, mert amikor elkezdtem erről a feature-ről még szó sem volt, ez nem rég jelent meg mint újabb igény.

hanem, hogy nem ilyet szeretnék, hanem olyat, amilyet már korábban leírtam.

értjük, te az a fajta vagy, aki még ha érti is, hogy lehetetlent kíván, akkor is ragaszkodik hozzá. értsd meg, hogy az, amilyet szeretnél, az nem tud működni. mivelhogy nem is arra való, mint amire szeretnéd használni.

Tehát vannak neked ilyen szűrőid, többféle.
Minden szűrő egy osztály.

Vannak fv-eid, amikben ilyen szűrőket használsz. És szeretnéd néha újrainicializálni benne a szűrőidet.

Jól értem?

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Arra gondoltam én is hogy van többféle szűrőd, és minden fv-ed használ pár sajátot (statikusan) ezekből.

Tehát most ilyened van:


void func1(...)
{
   static Filter1 filter1;
...
   //impl
}
...
for(...){
   for(...){
     ...
     func1(...);
     ...
   }
   //reset
}

Ehelyett legyenek a fv-ek objektumok. Ha funktort csinálsz belőlük, akkor alig kell változtatnod a kódodon:


class Func1
{
public:
   void operator() (...)
   {
      //impl
   }

private:
   Filter1 filter1;
   ...
};

...
for(...){
   Func1 func1;
   for(...){
     ...
     func1(...);
     ...
   }
}

És kész. A belső ciklushoz hozzá se nyúltál, a fv-ek átírása is szinte triviális.

Vagy:


class Func1
{
public:
   void operator() (...)
   {
      //impl
   }

   void reset()
   {
      //reset
   }

private:   
   Filter1 filter1;
   ...
};

static Func1 func1;

...
for(...){
   for(...){
     ...
     func1(...);
     ...
   }
   func1.reset();
}

Ennek az utóbbinak megvan az az előnye, hogy tényleg ugyanúgy használod a funktorokat mintha fv-ek lennének.
(És megvan az a hátránya ami egy statikus objektumnak általában: különböző fordítási egységekben található statikus objektumok inicializációjának sorrendje nem definiált.)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Ha úgy jobban tetszik, ezeket a képződményeket ne hívjuk funktornak. Csak osztályok amiknek véletlenül pont van egy operator() fv-e.
Ha így nézed ez teljesen ugyanaz, mint amit te írtál feljebb, csak így talán kevesebb kódot kell átírni...

A statikus példányok szépségén lehet vitatkozni, de én csak annyi mondok: cout.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Valójában nálam sem függvénnyel, hanem osztállyal van megvalósítva, majdnem pont úgy ahogy a példádban írtad.

A probléma az, hogy nem tehetem a példányok létrehozását a belső cikluson (pontosabban az abban meghívódó "nagy" függvényen) kívülre a már részletezett okok miatt.
Ahogy most kinéz, az marad, hogy a legfelső szintű interfészen keresztül kell rángatnom egy reset flaget.

hát, elvileg C++ lenne :)

Kis adalék a helyzet megértéséhez:

A belső ciklusban lévő dolgoknak "önhordónak" kell lenniük, mert a végső rendeltetésük nem abban a ciklusban futni, hanem egy dll-be (vagy más, dinamikusan linkelődő könyvtárba) lesznek fordítva. Ezért nem tehetek semmi olyat rajtuk kívülre, amire egyébként szükségük van.

Mivel ez ilyen cross-compiling-féle dolog, tehát a target az egyáltalán nem az a vas, amin fejlesztek, ezért a ciklusok, meg minden ami a belső ciklus magján (pontosabban az ott meghívott "nagy" függvényen) kívül van, az "csak" egyfajta tesztkörnyezet-féle. Ráadásul, erre az egész resetelős dologra csak itt van szükség, a targetre fordítva már nincs.

Ezekből következik, hogy lennie kell egy olyan interfésznek, ami csak szabványos függvényargumentumok átadására szolgál, ami mentén kettéválasztható a kód. Ezért nem lehet semmilyen globális változóval (ill. példányokkal) meg egyéb globális trükkel próbálkozni.

Amúgy most arra hajlok, hogy mégis megpróbálom valahogy globális változókkal, de az összes hacket feltételes fordítási makróba teszem, hogy a targetre ne forduljon be.

Akkor meg csinálj valami ilyet:
http://hup.pastebin.com/f4ac2a3de

Ez lesz neked a szép megoldás, főleg ha egy univerzális lib -et akarsz csinálni.
(Ha tényleg univerzális lib lesz, ne felejtsd el a megfelelő hívási konvenciót beállítani, az import headerben is, különben lehetnek egy-egy rendszeren meglepetések, pláne ha mondjuk nem C-ből, hanem valami más nyelvből akarják majd használni a libedet...)

Egyébként nézz rá a zlib -re, nagoyn ötletes, ahogy ott van ez megvalósítva.
gyakorlatilag az inflate()/deflate() függvények, amik a tömörtést/kitömörtést végzik, csak egy ilyesmi struct -ra mutató pointert kérnek paraméterül, és a programnak a stuct erre kijelölt mezőiben jelzik, ha a bemeneti buffer kifogyott, vagy a kimeneti buffer megtelt, ekkor a program beolvas adatokat, vagy kiírja azokat, etc.etc.

Ha nem gányolást akarsz, és tényleg rendes lib -et akarsz, akkor feltétlen ilyesmiben gondolkozz.

Aztán később csinálsz a libedhez egy C++ interfacet, ami egy wrapper class lesz csak.

Igen, tudtál, és a többieknek is köszönöm.

A legfontosabb hozadéka az volt a beszélgetésnek, hogy kiderült, hogy valószínűleg nem lehet úgy megoldani, ahogy eredetileg akartam. Ez sok időt megspórolt nekem, mert képes lettem volna napokig pörögni rajta, feleslegesen.

A hogyan tovább már egy másik kérdés, azt még nem tudom pontosan.

Es itt erkezett el az a pont, amikor jobban tudnank segiteni, ha nem csak kodos nagy titokzatos feladatrol beszelgetnenk, hanem valami, a fentinel konkretabb kodot is kapnank. Szerintem baromira elbeszelunk egymas mellett. Eddig nekem is ugy tunik, hogy a feladatra tervezett koncepcio az, ami el lett baltazva, es te most kinlodsz az elbaltazott koncepcio menten szuletett koddal.

Ha a cel a C kompatibilitas, azt barmikor ki lehet valtani wrapper fuggvenyek letrehozasaval, szoval ettol ne tarts.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

Én nem látom a lényegi különbséget aközött, hogy külön-külön minden változó statikus, és aközött, hogy egy osztályba vannak összefogva, és az egész objektum statikus.

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Ez oké, csak mi nem azért pofázunk itten osztályokról, hogy azokat csináld meg statikusra, hanem azért, hogy egyáltalán ne használj statikus változókat...

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

Itt többen vagyunk akik úgy gondoljuk, hogy elkerülhető lenne a statikus változók ilyen mértékű használata némi refactoring munkával.

Mivel te ezt nem akarod meglépni, ebből következik, hogy de, jókedvedben használod őket... :)

"...handing C++ to the average programmer seems roughly comparable to handing a loaded .45 to a chimpanzee." -- Ted Ts'o

vegigolvastam az egesz topicot.
Megbecsultem a programozoi tudasodat, es a programjaid bonyolultsagat.

Azt hiszem, neked a longjump() fuggvenyt kellen hasznalnod, olyan modon,
hogy a fuggvenyedben a static valtozo deklaralasa utan longjumppal elugrassz egy masik fuggvenybe, ott egy masik (globalis) valtozobol megtudod, hogy inizni kell-e a fuggveny static valtozojat vagy sem, es ezt megcsinalod, majd longjump() -pal visszaugrani az eredeti fuggvenybe.

Ez az egytlen megoldas, hogy meg idejeben teljesen menedzselhetetlen legyen a kodod, es kenytelen legyel kidobni es ujrairni az egeszet, mielott meg 2 ev munkat belefeccolsz.

happy hacking:-)

"vegigolvastam az egesz topicot.
Megbecsultem a programozoi tudasodat, es a programjaid bonyolultsagat."

Huhhh, hát ezt nagyon köszönöm, ritkaság, mert manapság nem szokás olvasni, csak írni :)

Nem egészen értem, hogy miért lenne jó nekem az ugrálás.

Most leginkább arra hajlok, hogy egy globális változóban kezelem az initflaget, de a függvény(ek)en belül a lekezelését makrón belülre teszem, úgy, hogy nem fog befordulni, ha a targetre fordítok.

Az ugralas arra jo, hogy az egesz projekten nyomj egy rm -rf -et duhodben, es vegre elkezdj ertelmes kodot irni. Vagy legalabbis ertelmes kerdeseket.

Ezt imadom, van egy kelloen kurvabonyolult problema, es akkor jonnek az altalanos peldaikkal, amire kapnak altalanos valaszt, majd kozlik, hogy a valasz neki nem jo, az egesz ugy ennel sokkal bonyolultabb. Hat ha bonyolultabb, akkor miert nem bonyolultabban kerdez?! Hatha akkor a valaszadok ugy 80%-a nem toszna el a sajat idejet azzal, hogy megprobalja rejtelyes kodositesekbol megfejteni egyfelol a kod kornyezetet, masfelol a kod celjait.
--


()=() Ki oda vagyik,
('Y') hol szall a galamb
C . C elszalasztja a
()_() kincset itt alant.

-nagyon rég volt már hogy ilyesmibe botlottam
-commenteket sem olvastam végig mert alig látok ki a fejemből
-veszélyes ez a módszer

hozz létre egy pointert a függvényen kívűl, és egy a pointerre mutató pointert adj át a függvénynek,
majd a függvényen belül irányítsd az eredeti pointert a statikus változó címére,
miután kilépett a függvény a pointeren keresztül változtasd a változód értékét

(egyáltalán nem vagyok benne biztos hogy ez működőképes ebben a formában de egy próbát megér, sry hogy nem tesztelem de ko)

glhf

Óriási mázlim van úgytűnik, proof-of-concept szinten már működik is a dolog :)

Az lett a nyerő, hogy csak az elkülönítendő függvényt tartalmazó fodítási egységbe kellett beszenvedni globális változós trükkel az init flaget, ez azt jelenti, hogy csak ezen a szinten kellett makrózni.
Utána az osztályokban egy, a működés sajátosságait kihasználó trükkel viszonylag fájdalommentesen sikerült alaphelyzetbe állítnai az állapotváltozókat.

Szerintem az a változó, amelyik csak a függvényen belül tartja az értékét, az pont a nem-statikus változó. Ha fontos, hogy ez a változó, egy külső statikus értéket vegyen alapul, akkor passzold a függvénynek az értéket. Vissza is lehet return-ölni - de akkor nem void lesz a függvényed.

Vagy nem értem pontosan a problémát.

"Jegyezze fel a vádhoz - utasította Metcalf őrnagy a tizedest, aki tudott gyorsírni. - Tiszteletlenül beszélt a feljebbvalójával, amikor nem pofázott közbe."