[{"data":1,"prerenderedAt":192},["ShallowReactive",2],{"lesson-raii":3,"lesson-navigation":171},{"id":4,"title":5,"body":6,"description":136,"extension":137,"label":138,"lessonId":139,"meta":140,"minutes":141,"navigation":142,"order":143,"path":144,"quiz":145,"seo":168,"slug":139,"stem":169,"__hash__":170},"lessons\u002Flessons\u002Fraii.md","Make cleanup someone’s actual job.",{"type":7,"value":8,"toc":131},"minimark",[9,14,18,25,67,78,82,89,92,95,99,105,110,127],[10,11,13],"h2",{"id":12},"the-mess","The mess",[15,16,17],"p",{},"Your AI puts cleanup at the bottom. Then you add an early return. Congratulations: a one-line edit now needs an incident report.",[15,19,20,24],{},[21,22,23],"strong",{},"RAII ties cleanup to an object's lifetime."," The acronym means Resource Acquisition Is Initialization. Apparently “automatic cleanup” wasn't hostile enough for the naming committee.",[26,27,32],"pre",{"className":28,"code":29,"language":30,"meta":31,"style":31},"language-cpp shiki shiki-themes github-light github-dark","void update() {\n    mutex.lock();\n    if (!ready()) return; \u002F\u002F Everyone else can wait. Forever, possibly.\n    mutex.unlock();\n}\n","cpp","",[33,34,35,43,49,55,61],"code",{"__ignoreMap":31},[36,37,40],"span",{"class":38,"line":39},"line",1,[36,41,42],{},"void update() {\n",[36,44,46],{"class":38,"line":45},2,[36,47,48],{},"    mutex.lock();\n",[36,50,52],{"class":38,"line":51},3,[36,53,54],{},"    if (!ready()) return; \u002F\u002F Everyone else can wait. Forever, possibly.\n",[36,56,58],{"class":38,"line":57},4,[36,59,60],{},"    mutex.unlock();\n",[36,62,64],{"class":38,"line":63},5,[36,65,66],{},"}\n",[15,68,69,70,73,74,77],{},"Here ",[33,71,72],{},"mutex"," and ",[33,75,76],{},"ready()"," already exist. That return skips the unlock. Other callers may get stuck waiting.",[10,79,81],{"id":80},"the-fix","The fix",[15,83,84,85,88],{},"Use ",[33,86,87],{},"std::lock_guard",": construction acquires the mutex; destruction releases it. Think automatic key return, instead of trusting every guest to remember checkout.",[15,90,91],{},"Constructed local guards are destroyed on ordinary scope exits, including early returns and exception unwinding. Existing owners also manage files and memory.",[15,93,94],{},"Forced process termination doesn't guarantee destructors run. RAII handles cleanup, not resurrection. You paid for autocomplete, not an exorcism.",[10,96,98],{"id":97},"ask-your-ai","Ask your AI",[100,101,102],"blockquote",{},[15,103,104],{},"Replace manual cleanup with an appropriate RAII owner. Show where it is destroyed on success, early return, and exception paths.",[15,106,107],{},[21,108,109],{},"Cleanup belongs in the design, not in your increasingly optimistic memory.",[15,111,112,113,120,121,126],{},"Receipts: ",[114,115,119],"a",{"href":116,"rel":117},"https:\u002F\u002Fisocpp.github.io\u002FCppCoreGuidelines\u002FCppCoreGuidelines#Rr-raii",[118],"nofollow","RAII guideline"," · ",[114,122,125],{"href":123,"rel":124},"https:\u002F\u002Feel.is\u002Fc++draft\u002Fthread.lock.guard",[118],"Lock guards",".",[128,129,130],"style",{},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":31,"searchDepth":45,"depth":45,"links":132},[133,134,135],{"id":12,"depth":45,"text":13},{"id":80,"depth":45,"text":81},{"id":97,"depth":45,"text":98},"Because “I’ll remember to clean up” has such an impressive production record.","md","RAII","raii",{},"2",true,"4","\u002Flessons\u002Fraii",[146,153,160],{"prompt":147,"options":148,"answer":39,"explanation":152},"Why can an unlock at the bottom fail you?",[149,150,151],"The compiler always removes it.","A return or exception can skip it.","Leaving any scope automatically unlocks a mutex.","A guard unlocks on destruction. A statement at the bottom requires reaching the bottom. Groundbreaking, apparently.",{"prompt":154,"options":155,"answer":45,"explanation":159},"Which resources can RAII manage?",[156,157,158],"Only heap memory.","Only resources without failure paths.","Locks, files, memory, and other owned resources.","RAII gives an object cleanup responsibility. Files and locks also need adults in the room.",{"prompt":161,"options":162,"answer":166,"explanation":167},"The OS forcibly kills the process. Will every destructor run?",[163,164,165],"No: forced termination offers no such guarantee.","Yes: RAII intercepts all process termination.","Yes: the OS runs the destructors itself.",0,"RAII covers destruction, including ordinary exits and exception unwinding. It does not negotiate with a killed process.",{"title":5,"description":136},"lessons\u002Fraii","Tw7ng0Ymwe5fq7e3b8iveSbNdeUOQf5ZpywXpF_rHVE",[172,176,179,183,184,188],{"lessonId":173,"slug":173,"title":174,"order":175},"ownership","Someone has to clean up.","1",{"lessonId":177,"slug":177,"title":178,"order":141},"lifetime","Your pointer outlived its welcome.",{"lessonId":180,"slug":180,"title":181,"order":182},"references-and-pointers","Borrowed doesn’t mean immortal.","3",{"lessonId":139,"slug":139,"title":5,"order":143},{"lessonId":185,"slug":185,"title":186,"order":187},"copies-and-moves","Moving is not a magic speed spell.","5",{"lessonId":189,"slug":189,"title":190,"order":191},"undefined-behavior","“It worked” is not a warranty.","6",1789406997109]