Kevin Lin zkouší využívat chytré brýle Mentra při hraní na piano. Vytváří aplikaci AugmentedChords, pomocí které si do brýlí posílá notový zápis (YouTube). Uvnitř brýlí běží AugmentOS (GitHub), tj. open source operační systém pro chytré brýle.
Jarní konference EurOpen.cz 2025 proběhne 26. až 28. května v Brandýse nad Labem. Věnována je programovacím jazykům, vývoji softwaru a programovacím technikám.
Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Před 25 lety zaplavil celý svět virus ILOVEYOU. Virus se šířil e-mailem, jenž nesl přílohu s názvem I Love You. Příjemci, zvědavému, kdo se do něj zamiloval, pak program spuštěný otevřením přílohy načetl z adresáře e-mailové adresy a na ně pak „milostný vzkaz“ poslal dál. Škody vznikaly jak zahlcením e-mailových serverů, tak i druhou činností viru, kterou bylo přemazání souborů uložených v napadeném počítači.
Byla vydána nová major verze 5.0.0 svobodného multiplatformního nástroje BleachBit (GitHub, Wikipedie) určeného především k efektivnímu čištění disku od nepotřebných souborů.
Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za duben (YouTube).
Provozovatel čínské sociální sítě TikTok dostal v Evropské unii pokutu 530 milionů eur (13,2 miliardy Kč) za nedostatky při ochraně osobních údajů. Ve svém oznámení to dnes uvedla irská Komise pro ochranu údajů (DPC), která jedná jménem EU. Zároveň TikToku nařídila, že pokud správu dat neuvede do šesti měsíců do souladu s požadavky, musí přestat posílat data o unijních uživatelích do Číny. TikTok uvedl, že se proti rozhodnutí odvolá.
Společnost JetBrains uvolnila Mellum, tj. svůj velký jazykový model (LLM) pro vývojáře, jako open source. Mellum podporuje programovací jazyky Java, Kotlin, Python, Go, PHP, C, C++, C#, JavaScript, TypeScript, CSS, HTML, Rust a Ruby.
Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.
V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
napriklad prave ta bezpecnost se lepe resi v jazycich s GC. Kazdopadne ja bych to radeji nez v C++ psal v D, ktere mi IMHO prijde na psani bezpecneho kodu o neco lepe vybavene a nebo rust
Staci si jen vzit, jak vrasky ted distribucim dela Go.To je imho spíš tím, že má přiblblej build systém + package management než tím, že to je cool nový jazyk...
Trebas pruser c. 1 je, ze aktualne je jen x86_64 only...Cože?
Cool jazyk je bez knihoven k ničemu.
C++ je pro psaní bezpečného kódu také velmi dobře vybaven, stačí nezneužívat jím poskytovanou volnost a programovat jako člověk, ne jako prase.
napriklad prave ta bezpecnost se lepe resi v jazycich s GC.Už jsem viděl příliš mnoho NullPointerException, race conditions, korupcí dat a podobně než abych nečemu takovému byl ochoten věřit...
NullPointerException a race conditions s tim nijak nesouvisi, ta korupce dat to je prave to cemu se snazi nektere jazyky dnes zabranit, samozrejme pokud vezmu v uvahu systemovy jazyk jako je D, tak ten ti samozrejme musi umoznit korupci dat :), ale to neznamena ze nema nastroje a moznosti jak se predtim chranit.
Tohle jsou problémy, které s GC nesouvisí – GC ti je nezpůsobí, způsobuješ si je sám i kdybys ho neměl, GC ti akorát řeší některé problémy, které bys bez něj musel ošetřovat ručně (což znamená riziko dalších chyb). A RAII taky není úplně marný přístup, to musím uznat i jako Javista
Za dobrou (bezpečnou) volbu považuji silně typovaný jazyk s GC nebo s RAII + nepoužívat nízkoúrovňové konstrukce (surové ukazatele, předčasná optimalizace atd.). Co se týče vícevláknového/víceprocesorového programování, je lepší použít nějaký framework/knihovnu, než spoléhat na magické schopnosti některých jazyků – některé věci prostě nejde automatizovat, nemůže to fungovat „samo“ – resp. může, ale blbě – a je potřeba mít možnost to ovlivnit (tzn. více či méně nepřímo s těmi vlákny je třeba pracovat).
Tohle jsou problémy, které s GC nesouvisíNo právě
Což ale nezpochybňuje pozitivní vliv GC (nebo striktního využívání RAII) na bezpečnost.
asi si to mel spatne napsane :D. Jinak vetsina meho kodu je v D stejne rychla a nekdy i rychlejsi nez v C++, ale samozrejme to casto je tim ze to v C++ neumim napsat tak dobre. Jinak by melo platit ze v D se da napsat stejne rychly kod jak v C++ za pouziti stejneho backendu, takze misto ldc nejspis gdc, teda pokud si to c++ nekompiloval clang kompilatorem to by pak to ldc bylo spravnejsi volbou.
A nemas ten kod nekde nahodou jeste? Jen ze bych zkusil zjistit co je na nem spatne, pripadne kde je problem v D ze to je pomale.
Asi tak, kdyby valná většina programátorů to dělala pro uživatele a ne pro pohodu, tak by nám stačilo pár mega na desktop a na většinu aplikací a šlahalo by to jak z praku. Ale komukoliv žel kdekdo si hraje s jakýmisi skriptovacími jazyky či pseudokódem protože je to jednoduché a kúúl a potřebujeme 10× až 100× víc paměti a procesor s výkonem jak kráva.
Jsem si říkal jestli nejsu pako, když jsem předělával Pascal (třeba i Delphi) do C++ (třeba C++Builder-u) kvůli výkonu a na něco použil čisté C, a ty rozdíly byli docela zanedbatelné oproti tomu, když to někdo pak udělá v těch dalších pseudokód či skriptovacích jazycích.
¡Kjucííí přestaňte skriptovat a začněte programovat!
Eh D neni skriptovaci jazyk a jeho vykonnost je srovnatelna s C a C++ a pametova narocnost je(muze byt) velmi mala. Duvodem proc to dneska zere vic je casto spis i to ze lidi na optimalizaci kaslou nehlede na tom v cem to je napsane.
Dynamické alokování tě v C++ jako uživatele knihovny vůbec nemusí zajímat.
Každé použití operátoru new v programu obvykle svědčí o špatném návrhu aplikace (o malloc ani nemluvě).
Uživatel knihovny prostě jen použije objekt, jehož implementace není jeho starost:
{
IOBuffer<char> myBuffer;
...
} // myBuffer zaniká
Pokud bude chtít autor IOBufferu ukládat data na heapu, může nadefinovat třeba tenhle atribut:
unique_ptr<deque<T>> data{new deque<T>};
Žádný destruktor není pro uvolňování paměti potřeba, o vše se postará unique_ptr a RAII.
Doporučuji k přečtení knihu A Tour of C++ od Stroustrupa.
{ Shape *shape = getShapeFromUser(); if (userWantsAPrintout()) { asyncPrint(shape); } if (userWantsToSeeTheShapeInAViewer()) { asyncView(shape); } }
if (userWantsAPrintout()) { emit asyncPrint(shape); }anebo si to napises sam, s tim ze ten shape vloziz do fronty a nejaky bg thread si to vyzvedne. To "novy" C++ nespadlo z nebe, ale znacna jeho cast uz byla implementovana v knihovne boost. A ten kdo pouzival boost, tak ten se pak nedivil.
Znamená to, že do té doby se nedala pamět správně managovat? Nebo měl každý svoje ad-hoc řešení (někdo použil jednu knihovnu, druhý jinou, třetí si to napsal sám, čtvrtý to nechal leakovat)?Asi tak, nicméně
unique_ptr
je fakt jednoduchej, "knihovna" je silný slovo, je to na pár řádek v header file. Jinak tuším, že unique_ptr
byl taky v TR 03.
A shared_ptr
není až tak o moc složitější, pokud máš k dispozici atomické integery.
Jak v C++ čistě řešit následující situaci?Např. pomocí toho
shared_ptr
.
getShapeFromUser()
nemá vracet unique_ptr, ale shared_ptr? Tj. autor té funkce musí předvídat, že shape se bude používat asynchronně? Nebo je to jinak?
1) Teď jsi mi dost srazil sebevědomí. https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a01099_source.html mi nepřijde "fakt jednoduchý" :(Tam jsou fíčury, který nutně nejsou potřeba a navíc to je gnuobfuskované
2) Znamená to, že getShapeFromUser() nemá vracet unique_ptr, ale shared_ptr? Tj. autor té funkce musí předvídat, že shape se bude používat asynchronně? Nebo je to jinak?To záleží na širším kontextu, těch možností je vícero. Pokud ti odněkud přijde raw pointer, můžeš si ho do
shared_ptr
zabalit dodatečně, pokud to dává smysl v dané situaci.
K tomu tvému kódu: Přijde mi to jako javismus (objekty se posílají kdykoli kdekoli, přístup se neřídí, není posílání objekty hodnotou,...). Ty dvě async funkce vypadají jako read-only operace, takže by bylo dost možná nejlepší vrátit z té funkce konstatní referenci, za předpokladu, že doba životnosti toho Shape
je někde vhodně spravována. Případně pokud je Shape
možné bez větších problémů kopírovat, mohlo by být lepší vracet ho hodnotou, ne poiterem. Některé frameworky (třeba zmíněný Qt) používají na podobné věci COW wrappery. Zkrátka opravdu to záleží na nějakém celkovém návrhu, protože takhle to je pouze kousek kódu vytržený z nějakého neznámého návrhu a pak nelze jednoznačně říct, jak by vypadal ekvivalent v C++.
{ shared_ptr<Shape> shape = getShapeFromUser(); if (userWantsAPrintout()) { asyncPrint(shape); } ... další, nesmírnědlouhotrvající práce }Pokud v tomto případě asyncPrint skončí rychle, během nesmírnědlouhotrvající práce bude shared_ptr na shape pořád alokovaný, je to tak? Rozumím tomu správně, že abych ho uvolnil včas, musel bych ho explicitně dekrementnout (je správná moje doměnka, že shared_ptr je implementován přes reference counting, takže zabírá pamět, dá se oblbnout cyklickou referencí, žere CPU při copy/delete), případně jeho použití uzavřít do samostatného bloku? @ivan Když v Jave napíšeš "a=b; c=a;" a to c se pak nekam preda, nic divnýho se neděje. Neděje se ani COW, děje se to, že konceptuálně se v Javě předávají pouze reference na objekty, objekty se nikdy samy od sebe nekopírují. Když už na nějaký objekt žádná reference nevede, tak se v GC časem zamete.
No, asi je to Javismus v tom smyslu, že prostě v těle té funkce getShapeFromUser nechci být nucen přemýšlet o tom, jak bude výsledek používán.Jenže to seš stejně vždycky nucen, a to jak co se správy paměti týče (v Javě je dán jeden způsob - to, že o něm v dané situaci nepřemýšlíš, neznamená, že neexistuje), tak i rozhraní.
Single responsibility principle - getShapeFromUser se má starat o získání shape od uživatele, a nic víc. To považuji za základ composable softwaru - jednotlivé komponenty mohu psát odděleně, a to, jak si je potom sestavím, záleží až na konkrétní situaci.Souhlasim, ale myslim si, že nemá smysl tohle řešit na úrovni jednotlivých funkcí, nebo dokonce i tříd. Spíš až modulů.
Jaký je v této situaci nejvhodnější návratový typ (pointeru)?Vždyť říkám, že to nemá jednoznačnou odpověď
Pokud v tomto případě asyncPrint skončí rychle, během nesmírnědlouhotrvající práce bude shared_ptr na shape pořád alokovaný, je to tak?
shared_ptr
předáš kopií, tj. naalokovaná bude ta kopie vevnitř té dlouhé operace. Ta původní kopie může klidně zaniknout. Kopírování shared_ptr
imho moc nežere (atomické integery). V paměti bude zabírat nejspíše stejně nebo méně jako hlavička objektu v JVM Ad composability: Proč bych to nemohl řešit na úrovni funkcí? Samozřejmě to ne vždy má smysl, ale když to smysl má, nemělo by mě v tom nic uměle omezovat.No záleží, co je to za funkci, pokud je někde na rozhraní knihovny, tak to souhlas, ale pokud je to jen jedna z X funkcí třídy Y modulu Z, tak se dá předpokládat, že navrhuju modul Z jako celek a ty funkce navrhuju s ohledem na to, že budou nějakým způsobem spolupracovat (samozřejmě by z toho neměly vzniknout špagety, to je zas druhej extrém...).
Vlastně nerozumím, čím je ta situace nějak specificky Javovská?V tom, že tě nenapdane uvažovat o vlastnitcví toho objektu (dokud nenarazíš na otázku převedení toho kódu do C++ nebo něčeho takového)...
Prostě chci implementovat funkci getShapeFromUser třeba do nějaké knihovny, a nemohu předvídat, jak se ji uživatelé rozhodnou použít. Je snad Javovské to, že nechávám to rozhodnutí na uživateli knihovny?Když budeš tu knihovnu psát v C++, budeš se muset rozhodnout, jakým způsobem se bude spravovat doba života toho objektu a uživatel to bude muset respektovat. Nicméně dá se to řešit tak, aby to uživatele neomezovalo.
Je to tak? Pokud ano, co konkrétně se mi nelíbilo bylo to, že nesmírnědlouhotrvající operace už shape k ničemu nepotřebuje, ale ten bude stejně dealokován až po jejím skončení (v tom konkrétním případě), zatímco GC by to uklidil o dost dřív.Ano je to tak a teď už rozumim otázce. Ty se můžeš vlastnictví toho objektu v
shared_ptr
zřeknout dřív, dokonce bys to tak měl udělat ve chvíli, kdy ten objekt už nepotřebuješ. Nemá smysl se ho držet dýl. V tom kódu výše bys mohl buď tu další práci přesunout za scope toho shared_ptr
nebo na tom shared_ptr
zavolat reset()
.
Co se týče GC, jestli by něco uklidil dřív nebo později dost dobře nemůžeš vědět...
Může nastat potřeba shared_ptr, pokud nedochází ke sdílení objektu mezi vlákny?Samozřejmě - např. pokud na ten objekt drží odkaz několik různých objektů a není jasné, kdo by měl být vlastník, ani kdo zůstane naživu jako poslední a uklidí.
dá se oblbnout cyklickou referencíProto kromě shared_ptr existuje ještě weak_ptr.
std::unique_ptr<Shape> readShape() { ... }
....
{
std::list<std::shared_ptr<Shape> > obdelniky;
std::list<std::shared_ptr<Shape> > zelene;
...
std::shared_ptr<Shape> tmp = readShape();
if (tmp.je_obdelnik()) obdelniky.push_back(tmp);
if (tmp.je_zeleny()) zelene.push_back(tmp);
...
/* na konci scope se vsechno uklidi */
}
Samozřejmě se shared_ptr dá často obejít (tady třeba uložením unique pointerů do dalšího seznamu, který bude jednoznačný vlastník a výše uvedené seznamy budou obsahovat obyčejné pointery), ale někdy se kvůli pohodlí hodí.
std::move()
.
Pokud v tomto případě asyncPrint skončí rychle, během nesmírnědlouhotrvající práce bude shared_ptr na shape pořád alokovaný, je to tak? Rozumím tomu správně, že abych ho uvolnil včas, musel bych ho explicitně dekrementnout (je správná moje doměnka, že shared_ptr je implementován přes reference counting, takže zabírá pamět, dá se oblbnout cyklickou referencí, žere CPU při copy/delete), případně jeho použití uzavřít do samostatného bloku?shared_ptr muze zabirat i 40B. V zavislosti od toho, co od nej ocekavas. Muze totiz obsahovat krome poiteru a citace i mutex anebo poiter na deleter funkci. S cyklickou referenci jsem se jeste nepotkal - i kdyz netvrdim ze to nemuze nastat. Automaticky pointer chapu jako vlastnika. Napriklad kdyz vytvarim pri parsovani AST (strom), tak sipky od korene smerem dolu jsou unique_ptr, protoze node "vlastni" svoje syny. Zatimco pointery smerem nahoru k otci jsou obycejne pointery (anebo observer_ptr). shared_ptr znamena sdilene vlastnictvi objektu - sdilenou odpovednost za objekt. Coz je sam o sobe problem - ve vetsine pripadu staci unique_ptr. Cyklicka reference potom znamena, ze se vsechny objekty vlastni nejak navzajem - coz je blbost.
{ unique_ptr<Shape> shape = std::make_unique<Shape>(getShapeFromUser()); if (userWantsAPrintout()) { asyncPrint.push(std::move(shape)); anebo asyncPrint.push(shape.get()); } if (userWantsToSeeTheShapeInAViewer()) { a tady uz to nefunguje. } }Tady opdavdu jde o to kdo tu instanci vlastni a ten je potom zodpovedny, za jeji zruseni. Z jedne intance unique_ptr do druhe se prirazuje pomoci std::move (resp. std::swap). Pokud se ta pravidla, zmeni tak je to potreba celkem slozite refactorovat. PS: tohle
shared_ptr<Shape> s_ptr = std::make_shared<Shape>(std::move(u_ptr));vyzvedne instanci z unique_ptr a vlozi ji do shared_ptr.
shared_ptr<Shape> s_ptr = std::make_shared<Shape>(std::move(u_ptr)); vyzvedne instanci z unique_ptr a vlozi ji do shared_ptr.shared_ptr<Shape> s_ptr(std::move(u_ptr)) by mělo stačit.
Není mi jasné, co by na tom pseudokódu mělo být složité k implementaci.
Není to triviální?
Co když potřebuji u toho bufferu měnit jeho velikost?Tyhle kontejnery jako
deque
a podobné mají dynamickou velikost, jinak by byly celkem k prdu Navíc bych nepovažoval C++ za zrovna bezpečný a blbu-vzdorného.C++ umoznuje psat bezpecny kod a od revize C++11/14 je k tomu dosti nastroju.
Minimálně bych se poohlížel po něčem co má garbage collector.Neni vubec potreba.
Tiskni
Sdílej: