Adresa lokální proměnné v C

Mirek

Re:Adresa lokální proměnné v C
« Odpověď #15 kdy: 19. 04. 2017, 16:08:07 »
Struktura kódu je takováto:
Kód: [Vybrat]
int main() {
  __block int c = 0;
  printf("%p\n", &c);
  dispatch_async(...);
  printf("%p\n", &c);
  ...
}
Ty dva printfy vypisují různé adresy. Potřebuju předat jiné asynchonní knihovně ukazatel na ten čítač jako parametr (void*), proto to řeším, ale nevím, jak to udělat bezpečně, aby ten ukazatel zůstal platný. Funkce main nakonec končí ve smyčce událostí, takže proměnné na zásobníku zůstávají platné.
Jak je přesně definovaný modifikátor __block na linuxu? Co to dělá?


v

Re:Adresa lokální proměnné v C
« Odpověď #16 kdy: 19. 04. 2017, 16:18:14 »

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Adresa lokální proměnné v C
« Odpověď #17 kdy: 19. 04. 2017, 16:31:43 »
Zdravím, potřeboval bych vysvětlit jednu podivnost. Na Linuxu používám libdispatch v kódu v C, vytvořím si čítač (int counter) a ten pak používám v blocích, které dávám do fronty. Na hlavním vlákně si chci občas přečíst hodnotu, mám tam ukazatel na counter, ale program při čtení *counter spadne. Evidentně to nějak souvisí s těmi bloky, když je fronta prázdná, kód běží. Má s touto knihovnou někdo zkušenosti?
Asi by tochtelo nekam hodit ten kod, nebo aspon ukazku. Co presne je mysleno tim lokalni promenna? Pokud je tim mysleno opravdu lokalni promenna tak na tu nedava smysl delat ukazatel a ten pouzivat nekde mimo, jelikoz to kam ten pointer ukazuje uz nemusi existovat

Struktura kódu je takováto:
Kód: [Vybrat]
int main() {
  __block int c = 0;
  printf("%p\n", &c);
  dispatch_async(...);
  printf("%p\n", &c);
  ...
}
Ty dva printfy vypisují různé adresy. Potřebuju předat jiné asynchonní knihovně ukazatel na ten čítač jako parametr (void*), proto to řeším, ale nevím, jak to udělat bezpečně, aby ten ukazatel zůstal platný. Funkce main nakonec končí ve smyčce událostí, takže proměnné na zásobníku zůstávají platné.
Když padá kód bez zjevné chyby, hodíme to na překladač. Někde v dispatch_async se volá Block_copy (kvůli zařazení do fronty), což obnáší kopii kontextu bloku ze zásobníku na haldu. Neměnitelné lokální proměnné se klonují, měnitelné se přealokují na haldě. Celé to řeší překladač a runtime, v knihovnách nic není. Taky pozor na to, že po posledním Block_release ta proměnná zmizí (automaticky se dealokuje). Ono to je celé trochu magie a __block je lepší nepoužívat.

zboj

  • *****
  • 1 507
    • Zobrazit profil
    • E-mail
Re:Adresa lokální proměnné v C
« Odpověď #18 kdy: 19. 04. 2017, 21:34:07 »
určitě je to lokální proměnná? https://en.wikipedia.org/wiki/Blocks_(C_language_extension)
Je lokální až do zavolání Block_copy, jenže když to dělá knihovna, tak člověk neví, co se kdy děje. Aspoň to ale funguje lépe než v C#.

Trollopata

Re:Adresa lokální proměnné v C
« Odpověď #19 kdy: 19. 04. 2017, 22:27:06 »
Takové starosti bych chtěl mít, zlatá Java...