LINUXSOFT.cz Přeskoč levou lištu

ARCHIV



   

> Diskuze: článek C++ a garbage collector

To je hlod
(link)
27.8.2014 11:19
Jan Němec
Věk: ( ~47 let)

Ježíši, to je zase C++ hlod, s Váma bych nechtěl dělat v jednom týmu :-) Jinak bych doporučoval nenechávat se unést fanouškovstvím pro C++ (nebo některé jeho vlastnosti) a aspoň trochu se snažit o objektivitu. V zásadě bych řekl, že třeba

"C++ dotáhl uklízení lokálních proměnných na plný automatický úklid a to pro jakékoli proměnné jakéhokoli typu." (Ne. V C++ si můžu ručně naalokovat pointr, klidně přes malloc, ten se sám od sebe neuvolní.)

"RAII je voláno okamžitě bez prodlení a přesně v čase, kdy zdroj přestává být potřeba." (Ne. Destruktor se volá v době konce platnosti proměnné. Čert ví, kdy opravdu přestává být potřeba, lokální proměnná klidně v půlce bloku.)

"'Má nebo nemá C++ garbage collector?' Jak vidíte, odpovědět jde opravdu těžko." (Nemá. Má automatické volání destruktoru, má auto pointer, můžu si sám napsat nějaký jiný smart pointer... Ale garbage collector C++ nemá.)

"pokud se v C++ někdo musí starat ručně o uvolňování paměti, tak neprogramuje v C++" (C++ je všechno to, co je v normě C++, tj. i skoro celé skoro nezměněné C. Když programuju aspoň trochu normálně v C, tak programuju zároveň i v C++.)

jsou už zcela jednoznačně nepravdy.

Re: To je hlod
(link)
5.9.2014 15:18
Miloslav Ponkrác

1) "C++ dotáhl uklízení lokálních proměnných na plný automatický úklid a to pro jakékoli proměnné jakéhokoli typu." (Ne. V C++ si můžu ručně naalokovat pointr, klidně přes malloc, ten se sám od sebe neuvolní.)

Podstatný je ten termín „lokální proměnné“.

Jak jsem psal v článku, budete-li chtít pointery řešit ručně, C++ do toho zasahovat nebude. Budete-li je chtít uvolňovat automaticky, pak to samozřejmě lze, a to i u pointerů alokovaných pomocí malloc. Stačí ho šoupnout do chytrého pointeru a dále na to zapomenout. Nic se nezmění, syntaxe nakládání s pointerem je stejná, jako v případě ručného ošetřování. Jen se automaticky uvolní, až nebude třeba.

----

2) "RAII je voláno okamžitě bez prodlení a přesně v čase, kdy zdroj přestává být potřeba." (Ne. Destruktor se volá v době konce platnosti proměnné. Čert ví, kdy opravdu přestává být potřeba, lokální proměnná klidně v půlce bloku.)

Je takový nepsaný zvyk, dobrý zvyk ze starých časů, že obory platnosti proměnných (scope) korespondují s dobou potřeby daných proměnných. Je to základní poučka, která se jako první učí v sw inženýrství.

Pro nouzový, velmi nepravdědpobný případ, kdy zdroj nutně potřebujete uvolnit dříve, existují metody jako je release() či close(). Ovšem takový případ také něco říká o stylu daného kódera.

----

3) "'Má nebo nemá C++ garbage collector?' Jak vidíte, odpovědět jde opravdu těžko." (Nemá. Má automatické volání destruktoru, má auto pointer, můžu si sám napsat nějaký jiný smart pointer... Ale garbage collector C++ nemá.)

A jakápak je definice slova „garbage collector“? Pro jistotu ji opíši z wikipedie: „In computer science, <b>garbage collection (GC) is a form of automatic memory management.</b>“

Jakmile nepotřebujete ručně ve zdrojovém kódu uvolňovat paměť, tak se nejedná, po Klausovsku zůdrazňuji opakovaně, nejedná, o manuální uvolňování paměti, ale o automatické uvolňování paměti, tedy garbage collector.

----

4) "pokud se v C++ někdo musí starat ručně o uvolňování paměti, tak neprogramuje v C++" (C++ je všechno to, co je v normě C++, tj. i skoro celé skoro nezměněné C. Když programuju aspoň trochu normálně v C, tak programuju zároveň i v C++.)

Myslím, že je jasné, že jsem mluvil o stylu programování.

Toto není ani vědecká, ani právnická práce, je to úvaha a článek psaný běžným lidským jazykem.

Staré profláklé heslo „jsou programátoři, kteří programují ve Fortranu v každém programovacím jazyce“ snad napoví, o čem je řeč.

Existují programátoři, u kterých poznáte, že znají jeden programovací jazyk, a to i když programují třeba ve 20 jazycích. Jsou programátoři, kteří „programují v Javě v každém programovacím jazykce“, stejně tak jako jsou programátoři, kterří „programují v C v jakémkoli programovacím jazyce“, atd.

Re: To je hlod
(link)
8.9.2014 11:28
Jan Němec
Věk: ( ~47 let)

"Je takový nepsaný zvyk, dobrý zvyk ze starých časů, že obory platnosti proměnných (scope) korespondují s dobou potřeby daných proměnných. Je to základní poučka, která se jako první učí v sw inženýrství."


void [trida::]funkce_nebo_metoda()
{
typ jednoducha_promenna_nic_velkeho;
// neco delam s promennou

// posledni pouziti promenne
nejaky_kod_treba_i_jen_jeden_radek_bez_promenne();
}

Vám tohle přijde jako prasárna? To jako fakt dáváte to použití jednoducha_promenna_nic_velkeho do bloku nebo to rezepíšete na 2 funkce? (Pokud ne, tak rozhodně není pravda, že "RAII je voláno okamžitě bez prodlení a přesně v čase, kdy zdroj přestává být potřeba.")

Re: To je hlod
(link)
8.9.2014 16:26
Miloslav Ponkrác

Myslím, že slovíčkaříme. Jsem rád, že jsem Vám vysvětlil, a neprotestujete, že bloky by měly plus mínus korespondovat u dobrého stylu s platností lokálních proměnných. Souhlasím s tím, že RAII neruší proměnnou přesně v době, kdy zdroj přestává být potřeba, to opravdu neumí, ale v okamžiku konce platnosti proměnné. Na druhé straně právě proto jsem psal o programátorském stylu. Protože kompilátor není věštec, a tak dobu, kdy je proměnná potřeba odhaduje z jejího oborou platnosti + z jejího použití.

Závěr: V tom máte pravdu. Já jsem v článku předpokládal, že programujeme dobrým stylem. Máte pravdu, že RAII neruší v době, kdy není proměnná potřeba. To kompilátor opravdu nemá v mnoha případech jak poznat. Ovšem programátor má učinit dobu platnosti proměnné a její potřebnost do souladu. Tam, kde na tom záleží, a proměnná drží významné zdroje se prostě udělá separátní blok, nebo se zdroj odtraní ručně.

********

Pro kompilátor je jakákoli proměnná potřeba až do konce jejího oboru platnosti. Jak jistě víte, kompilátor nemusí provádět kód v té sekvenci příkazů, kterou jste napsal, a je oprávněn přehazovat pořadí příkazů, pokud to nezmění výsledné chování.

Teoreticky kompilátor ruší lokální proměnné na konci bloku, ve skutečnosti je může zrušit i dříve, přesně po čase posledního použití, pokud optimalizátor vydedukuje, že se tím docílí stejného chování, jako kdyby se zrušila na konci platnosti. A C++ kompilátor většinu proměnných zruší mnohem dříve, než je obor platnosti – doporučuji disassemblovat nějaký výsledný kód dobře optimalizující kompilátoru. Budete se hodně divit.

Re: To je hlod
(link)
22.9.2014 08:35
Aleš Hakl
Bydliště: Praha

Kompilator generuje kod, jehoz pozorovatelne chovani je stejne, jako kdyby se v nejakem poradi provedli casti oddelene sequence-pointy.

Kompilator umi pomerne snadno dokazat, ze promenna uz neni dale v bloku potreba, co ovsem dokazat rozumne neumi je, ze presun volani netrivialniho destruktoru z konce bloku nekam jinam chovani nezmeni (to stejne plati i o miste volani konstruktoru). Takovy prakticky priklad toho, kdy zmeni je promenna reprezentujici drzeny zamek (class F{ F() {pthread_mutex_lock(foo);}; ~F(){pthread_mutex_unlock(foo);} }), nebo obecne cokoli, co globalni stav programu ovlivnuje svoji prostou existenci, tj. veci ktere se uvadeji jako typicke priklady toho spravneho RAII.

Je to zase dalsi z mist, kde C++ garantuje/umoznuje neco, co vicemene zbytecne zamezuje spouste optimalizacnich prilezitosti.

Re: To je hlod
(link)
25.9.2014 03:11
Miloslav Ponkrác

Programovací jazyk umí využít k optimalizaci jen to, co se dá vydedukovat ze zdrojového kódu. Tedy z informace, kterou dodal programátor.

Programovací jazyk něco garantuje, a je na programátorovi, aby si na základě garancí udělal co potřebuje. Garance dokonalého uklizení lokálních proměnných a garance, že program bude dělat to, co je napsáno ve zdrojovém kódu – jsou docela nezbytností.

----

To hlavní, co brání optimalizaci v C/C++ je pointerová artimetika a nešťastná syntaxe pointerové aritmetiky. Program musí předpokládat, že pointery na cokoli se mohou objevit kdekoli v programu a nemůže téměř nic odvozovat. Kompilátor předá funkci pointer na strukturu, a musí předpokládat, že odteď může být struktura čtena i zapisována kdekoli v programu až do konce programu (samozřejmě s omezením na scope). A že se kdekoli mohou objevit pointery i na podčásti struktury. S tímto se hodně blbě optimalizuje.

C/C++ není schopno dost dobře si udělat systém vzájemných vztahů mezi proměnnými, funkcemi a thready uvnitř programu, protože pointerová aritmetika, stejně jako omezené informace mu to ani nedovolí.

Re: To je hlod
(link)
8.9.2014 16:29
Miloslav Ponkrác

Možná by se to dalo zkrátit: Proměnná je potřeba, dokud je v oboru platnosti. Tečka.

Re: To je hlod
(link)
29.9.2014 15:35
Jan Němec
Věk: ( ~47 let)

To je skoro takové tvrzení, jako "Je třeba tolik rohlíků, kolik naplánuje plánovací komise. Tečka." nebo v kapitalistické variantě "Je třeba tolik rohlíků, kolik zařídí neviditelná ruka trhu. Tečka." Nebo možná ještě názorněji "Vypůjčené nářadí potřebuji vždy přesně tak dlouho, dokud ho nevrátím." Ve skutečnosti ani jedno z těch tvrzení není pravda. Kdyby C++ uměl uvolňovat proměnné přesně v místě, kdy už nejsou potřeba, tak by musel překladač řešit problém zastavení (Turingova stroje). Nic proti uvolňování na konci platnosti proměnné, je to naprosto normální věc. Jen bych to nenazýval tím reklamním sloganem, to je vše.

Re: To je hlod
(link)
1.10.2014 00:26
Miloslav Ponkrác

Jak víte, že C++ kompilátor problém, kdy přesně nejsou proměnné potřeba neřeší? Samozřejmě že řeší, byť to závisí na kompilátoru, a většinou v tom není úspěšný ve složitějších případech, ale v jednodušších je to dnes běžné chování optimalizujících kompilátorů.

Jinak samozřejmě tato debata je opravdu hloupá. Kompilátor má údaje od programátora ze zdrojového kódu. Plus vše, co lze ze zdrojového kódu (a vlastností cílového prostředí platformy překladu) vydedukovat. Není to mnoho, ale není to vůbec málo.

Když potřebujete hodnotu typu integer, tak mu to napíšete, a nehádáte se v žádné diskusi, že má kompilátor číst myšlenky, a že to nepozná. Nedokáži si představit, že bychom diskutovali už kolikátý příspěvek o tom, že jste dal jiný typ než chcete a viníte kompilátor, že to nepoznal.

Když potřebujete někde suše ukončit s jistotou platnost proměnné, ukončíte mu tam blok. Je to zcela stejné. Přesto diskutujeme už x příspěvků, kde nejdříve jsem byl nucen napsal, že „proměnná je potřeba“ znamená v programátorském jazyce „je v oboru platnosti“ a programátor by měl tento záměr co nejvíce naznačovat takto.

Už po x-té se tu hádáme, že kompilátor C++ není schopen vydedukovat, že proměnnou je možné zrušit dříve, než před koncem oboru platnosti. Samozřejmě že v řadě případů je toho schopen, ale závisí to na kompilátoru a kvalitě jeho optimalizátoru. Bez této dedukce by z kompilátorů lezl velmi pomalý a nehezký kód. Ovšem jistota dedukce zde není, protože chcete-li jistotu, je jasně řečeno, že obor platnosti je tvrdá informace kompilátoru o potřebnosti proměnné. A vytvoření dodatečného bloku je zdarma.

Buď budete mluvit s kompilátorem způsobem, kterému rozumí, a nebo to nebude fungovat.

Díky za článek
(link)
4.9.2014 14:14
František Kučera
Věk: ( ~40 let) , Pracovní pozice: programátor , Praxe v IT let: ( ~10 let) , Bydliště: Praha

Musím přidat i jeden pozitivní komentář. Sice jsem skalní Javista, ale rád se naučím i něco jiného a podívám se, jak to řeší jinde.

Ten RAII princip je zajímavý. A v Javě na ho vlastně máme taky: try + AutoCloseable – sice to přidává složené závorky a další úroveň zanoření, ale zdroj se zavře ve chvíli, kdy končí platnost proměnné (zavolá se close(), což je důležitější – i když paměť požere GC až o něco později).

Ale uvítal bych trochu víc rozvést využití tohoto principu v případě, kdy se objekty předávají někam dál a nejsou jen v lokálních proměnných (tam je snadno pochopitelné), to jsem z toho příkladu moc nepochopil resp. přijde mi, že bude spousta případů, kdy to nebude fungovat a ty zdroje se samy nezavřou a neuvolní.

Re: Díky za článek
(link)
5.9.2014 15:34
Miloslav Ponkrác

Přiznám se, že v Javě mé znalosti nejsou zcela úplné, ale po Vašem příspěvku mě Java v tomto aspektu začala zajímat. Takže jste mě motivoval ke studiu.

Možná jsem měl článek napsat trochu konkrétněji, nebo napsat druhý díl s příklady. Celý princip automatického uklízení v C++ vychází ze dvou principů:

1) První princip je RAII. Pokud pointer zůstává uvnitř funkce/metody, či jednoho bloku uvnitř metody, pak stačí RAII. Ve standardní knihovně existuje několik tříd zvaných chytré pointery, do kterých pointer uložíte, a dojde k automatického uvolnění na konci oboru platnosti. S pointerem můžete zacházet dále dle libosti.

2) Druhý princip je syntaktický cukr udělaný pomocí „chytrého pointeru“. C++ má přetěžování operátorů a tak může vytvořit třídu („chytrý pointer“), který bude reagovat prakticky syntakticky stejně v C++ jako pravý pointer.

Pokud předáváte pointery mimo funkce/metody, třeba jako návratové hodnoty, a nebo pointery cestují a rozkopírovávají se na různá místa, pak je třeba použít jak RAII, tak ten syntaktický cukr chytrého pointeru. Ve skutečnosti nevracíte pointer, ale třídu „chytrý pointer“.

Programátor nepozná rozdíl (kromě typu), protože s chytrým pointerem se zachází stejně jako s pointerem. Ale protože je „chytrý pointer“ třída, a dokonce si ji můžete napsat i sám, pokud byste nechtěl používat standardní knihovnu, tak udělá cokoli budete chtít. Jeden z chytrých pointerů – třída std::shared_ptr má uvnitř čítač odkazů, a tedy počítá, na kolika místech se pointer vyskytuje. A když čítač dosáhne nuly, tak zdroj uvolní.

---

Podstata tedy v podstatě je v tom, že pokud se dostane pointer či jiný zdroj mimo lokální kontextu, ve skutečnosti se podstrčí namísto pointeru či zdroje obálka z chytrého pointeru.

Re: Díky za článek
(link)
9.9.2014 15:58
František Kučera
Věk: ( ~40 let) , Pracovní pozice: programátor , Praxe v IT let: ( ~10 let) , Bydliště: Praha
Rozepsal jsem to trochu v blogu: Java a princip RAII (CADRe) známý z C++

DISKUZE

To je hlod 27.8.2014 11:19 Jan Němec
L Re: To je hlod 5.9.2014 15:18 Miloslav Ponkrác
  L Re: To je hlod 8.9.2014 11:28 Jan Němec
    |- Re: To je hlod 8.9.2014 16:26 Miloslav Ponkrác
    | L Re: To je hlod 22.9.2014 08:35 Aleš Hakl
    |   L Re: To je hlod 25.9.2014 03:11 Miloslav Ponkrác
    L Re: To je hlod 8.9.2014 16:29 Miloslav Ponkrác
      L Re: To je hlod 29.9.2014 15:35 Jan Němec
        L Re: To je hlod 1.10.2014 00:26 Miloslav Ponkrác
Díky za článek 4.9.2014 14:14 František Kučera
  L Re: Díky za článek 5.9.2014 15:34 Miloslav Ponkrác
    L Re: Díky za článek 9.9.2014 15:58 František Kučera




Příspívat do diskuze mohou pouze registrovaní uživatelé.
> Vyhledávání software
> Vyhledávání článků

28.11.2018 23:56 /František Kučera
Prosincový sraz spolku OpenAlt se koná ve středu 5.12.2018 od 16:00 na adrese Zikova 1903/4, Praha 6. Tentokrát navštívíme organizaci CESNET. Na programu jsou dvě přednášky: Distribuované úložiště Ceph (Michal Strnad) a Plně šifrovaný disk na moderním systému (Ondřej Caletka). Následně se přesuneme do některé z nedalekých restaurací, kde budeme pokračovat v diskusi.
Komentářů: 1

12.11.2018 21:28 /Redakce Linuxsoft.cz
22. listopadu 2018 se koná v Praze na Karlově náměstí již pátý ročník konference s tématem Datová centra pro business, která nabídne odpovědi na aktuální a často řešené otázky: Jaké jsou aktuální trendy v oblasti datových center a jak je optimálně využít pro vlastní prospěch? Jak si zajistit odpovídající služby datových center? Podle jakých kritérií vybírat dodavatele služeb? Jak volit vhodné součásti infrastruktury při budování či rozšiřování vlastního datového centra? Jak efektivně datové centrum spravovat? Jak co nejlépe eliminovat možná rizika? apod. Příznivci LinuxSoftu mohou při registraci uplatnit kód LIN350, který jim přinese zvýhodněné vstupné s 50% slevou.
Přidat komentář

6.11.2018 2:04 /František Kučera
Říjnový pražský sraz spolku OpenAlt se koná v listopadu – již tento čtvrtek – 8. 11. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma umění a technologie, IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář

4.10.2018 21:30 /Ondřej Čečák
LinuxDays 2018 již tento víkend, registrace je otevřená.
Přidat komentář

18.9.2018 23:30 /František Kučera
Zářijový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 20. 9. 2018 od 18:00 v Radegastovně Perón (Stroupežnického 20, Praha 5). Tentokrát bez oficiální přednášky, ale zato s dobrým jídlem a pivem – volná diskuse na téma IoT, CNC, svobodný software, hardware a další hračky.
Přidat komentář

9.9.2018 14:15 /Redakce Linuxsoft.cz
20.9.2018 proběhne v pražském Kongresovém centru Vavruška konference Mobilní řešení pro business. Návštěvníci si vyslechnou mimo jiné přednášky na témata: Nejdůležitější aktuální trendy v oblasti mobilních technologií, správa a zabezpečení mobilních zařízení ve firmách, jak mobilně přistupovat k informačnímu systému firmy, kdy se vyplatí používat odolná mobilní zařízení nebo jak zabezpečit mobilní komunikaci.
Přidat komentář

12.8.2018 16:58 /František Kučera
Srpnový pražský sraz spolku OpenAlt se koná ve čtvrtek – 16. 8. 2018 od 19:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát jsou tématem srazu databáze prezentaci svého projektu si pro nás připravil Standa Dzik. Dále bude prostor, abychom probrali nápady na využití IoT a sítě The Things Network, případně další témata.
Přidat komentář

16.7.2018 1:05 /František Kučera
Červencový pražský sraz spolku OpenAlt se koná již tento čtvrtek – 19. 7. 2018 od 18:00 v Kavárně Ideál (Sázavská 30, Praha), kde máme rezervovaný salonek. Tentokrát bude přednáška na téma: automatizační nástroj Ansible, kterou si připravil Martin Vicián.
Přidat komentář

   Více ...   Přidat zprávičku

> Poslední diskuze

31.7.2023 14:13 / Linda Graham
iPhone Services

30.11.2022 9:32 / Kyle McDermott
Hosting download unavailable

13.12.2018 10:57 / Jan Mareš
Re: zavináč

2.12.2018 23:56 / František Kučera
Sraz

5.10.2018 17:12 / Jakub Kuljovsky
Re: Jaký kurz a software by jste doporučili pro začínajcího kodéra?

Více ...

ISSN 1801-3805 | Provozovatel: Pavel Kysilka, IČ: 72868490 (2003-2024) | mail at linuxsoft dot cz | Design: www.megadesign.cz | Textová verze