4 ms·
The canonical method in C is to jump to a named label which hosts some functions to unwind/close any open descriptors or operations. As it involves the use of a
by vezzy-fnord 11y ago
The canonical method in C is to jump to a named label which hosts some functions to unwind/close any open descriptors or operations. As it involves the use of a goto statement, it drives certain people mad.
I wasn't aware of C Blocks.
- baq 11y agothe problem with goto for error handling is possibility of programmer error: you have to keep track of the order of labels yourself, whereas defer does that for you. i won't comment on anti-goto fascism.
- geocar 11y agoClang's blocks produce atrocious code. Look at the disassembly for: int main(){ __block int (^foo)(int x) = ^ int (int x) { if(x<100) return foo(x+10); return x; }; return foo(69); } versus the GCC: int main(){ int foo(int x) { if(x<100) return foo(x+10); return x; }; return foo(69); } if you want to see what I'm talking about. CLANG: http://pastebin.com/37A9by4V http://pastebin.com/37A9by4V GCC: http://pastebin.com/RMEDnwxi http://pastebin.com/RMEDnwxi However, defer does look interesting, and implementing it for GCC is very easy: #define defer_(x) do{}while(0); \ auto void _dtor1_##x(); \ auto void _dtor2_##x(); \ int __attribute__((cleanup(_dtor2_##x))) _dtorV_##x=69; \ void _dtor2_##x(){if(_dtorV_##x==42)return _dtor1_##x();};_dtorV_##x=42; \ void _dtor1_##x() #define defer__(x) defer_(x) #define defer defer__(__COUNTER__) You don't have to use the stupid block-syntax either, just: in = fopen("whatever", "r"); defer { fclose(in); }
- raimue 11y agoWhat purpose does the empty do{}while(0); statement serve here?
- gp7 11y agoIt puts the whole #define code into a single expression so you can do if (cond) MACRO; and the macro won't expand incorrectly to if (cond) foo; bar; I personally just go the anal retentive route and use brackets everywhere.
- cthrowappp 11y agoNot in this case it doesn't.
- geocar 11y agoNo syntax error if someone writes if(x)defer. Probably better to have a big error message since we can't curry the if. if(x){defer} will be wrong, but it'll be wrong in a different way.
- cthrowappp 11y agoThat's pretty cute.
- detrino 11y agoLast time I looked at it, BOOST_SCOPE_EXIT_ALL generated similarly atrocious code, which is a shame because you can write a zero-cost construct in C++11 very easily.