Jak Microsoft (ne)opravuje bugy

5. 4. 2012 9:54 zboj

Když vyšlo na podzim první dev preview Windows 8, docela mě bavilo „hrabat“ se ve WinRT, jelikož to bylo něco nového. Podobnost C++/CX s ObjC a Cocoa (jistě „čistě náhodná“) sváděla k porovnání různých koceptů. Protože ve WinRT má Microsoft kvůli návaznosti na jiné jazyky (a zejména .NET, tedy CLR) tzv. „projekce“, nelze lambda výrazy používat přímo, ale zabalují se do „delegátů“. Takový delegát se chová stejně jako C++/CX komponenta, tedy zejména má čítač referencí. Na druhou stranu zabalená lambda je nativní C++ objekt a správa paměti (např. při přesunu ze zásobníku na haldu) se řeší kopírováním (nebo novým move). Člověk by čekal, že použití instance komponenty v lambda výrazu jí zvýší čítač referencí a po zániku lambda výrazu jej opět sníží. Tak to i funguje, než ovšem předáte lambda výraz delegátu, kde správa paměti selže a máte memory leak jak vyšitý.

Připomeňme, že Apple, ať už s ARC nebo bez, automaticky zvyšuje čítač referencí (pokud se nepoužije __block, __weak nebo podobný modifikátor), přičemž bloky (obdoba lambda výrazů podle normy) včetně kontextu (closure) kopíruje ze zásobníku na haldu automaticky. Dokud nevytvoříte referenční cyklus (což je u bloků poměrně časté, aniž by si toho člověk všimnul, vzhledem k implicitnímu self u instančních proměnných), vše šlape hladce (blok samotný se chová jako ObjC objekt a má svůj čítač referencí).

V říjnu jsem na tento problém ve WinRT upozornil (na fóru a následně v bug trackingu), reakce byla (po řadě) skepse („to je tak jednoduchý koncept, tam nemůže být bug“), údiv, uznání a nakonec slíbení nápravy v beta verzi. Schválně si to zkuste teď, co myslíte, došlo k opravě?

Sdílet