12 ms·
They should add something to run code when leaving a scope, no matter how you leave the scope (break, return, ...). That would allow cleanup and other such act
by Aardwolf 8y ago
They should add something to run code when leaving a scope, no matter how you leave the scope (break, return, ...).
That would allow cleanup and other such actions without resorting to such hacks as: "goto cleanup" pattern, separate functions, fake for loop to break out of, ...
- majewsky 8y agoThe idiomatic way to do that is with destructors. EDIT: Sorry for the confusion, I misread the article and thought this was about C++2x.
- mouldysammich 8y agoC doesn't have destructors, does it?
- vkazanov 8y agoYeah... Actually adding something like defer {...clean up code...} would be really nice. But who are we to ask..? Just programmers, i.e. mere mortals nobody really cares about. :-)
- stinos 8y agoYou can use C++ as some kind of C with destructors though :P Scoped cleanup is really a nice thing.. But then you also want templates of course to get rid of your void*. And oh, wait, what's that? A cross-platform thread implementation (well, sort of, depends on platform)? A string thing which I can search without strstr? Anonymous functions which capture? Auto? Gimme gimme :]
- beefhash 8y ago> You can use C++ as some kind of C with destructors though :P Scoped cleanup is really a nice thing.. C++ is not a strict superset of C. You actually have to cast void pointers, for example. > But then you also want templates of course to get rid of your void*. No, actually, I think I can live without that, but thank you. > And oh, wait, what's that? A cross-platform thread implementation (well, sort of, depends on platform)? C11, threads.h. Been there, got that. > A string thing which I can search without strstr? Okay, I'll give you that, string handling is hell. > Anonymous functions which capture? Have their uses, but I'm not sure if C is really the right place for it. > Auto? auto (as used in C++11 and later) is a solution in need of a problem in C. When you don't have piles of templates and iterators, you also tend not to need to automatically derive types. In a world where signed/unsigned integer comparison can have fatal consequences, you probably do want to be very sure about your types.
- rubber_duck 8y ago>C++ is not a strict subset of C. I think you flipped this :) ?
- stinos 8y ago> C++ is not a strict superset of C. I know that. I use both C and C++ practically daily. The post was partly joking. But only partly (for example of course I could live without templates if really needed but seriously they make some jobs a lot better and easier). Hence I aptly phrased it some kind of C hoping (idly it seems) no one would trip over it because it's obviously not C.
- Dylan16807 8y agoI don't think those other features are half as compelling as you think they are.
- stinos 8y agoUsing both C and C++, each in their place, I actually do think they are.
- Dylan16807 8y agoThen why ever use C if they're that compelling? I'm not really understanding how wanting one little thing from C++ implies diving all the way in.
- stinos 8y agoThen why ever use C Because some platforms I've used it on did't have proper C++ support. Or because a project I contribute to is already written in C. Or because of limited resources. Etc. I'm not really understanding how wanting one little thing from C++ implies diving all the way in. It's just an example of a possible train of thought. And I wouldn't call something like templates 'one little thing'. So suppose there's a choice between both, and no limit on resources etc, and I could go for everything C but templates could make everything easier then just going for C++ instead is an option. Even when not going 'all in' and writing what looks like standard C + template support.
- Dylan16807 8y ago> And I wouldn't call something like templates 'one little thing'. Agreed. But templates aren't the one little thing, they're something you said would be 'next'. The 'one little thing' is a way to replace the GOTOs used for releasing resources. I think it's an easy argument that when people are repeatedly building a pattern out of GOTO, there's a gap in the control flow tools that a language gives you.
- maxxxxx 8y agoSometimes I wonder if a C++ without inheritance would be the right thing. All the crazy design abuses I have seen were around inheritance. Other things like auto and anonymous functions are just super useful and I wouldn't want to miss them.
- jfoutz 8y agoAuto is already taken in C. It’s the default, rather than register or static, so you hardly ever see it
- kazinator 8y agoauto was taken in exactly the same way in C++ until fairly recently. They re-purposed it because it was obsolescent. auto was already in vanishing disuse in C at the time ANSI C came out in 1989. The C++ use of auto resurrects an aspect of the way auto was used in the C predecessor languages B and NB. In these pre-C languages, everything was an integer cell. A declaration of local variables looked like this: auto x, y; the auto meant automatic storage (stack), but the real purpose here is syntactic: the auto is a declaration specifier, which makes the above construct a declaration. There is no indication of type, because it is implicit. Without the auto it would look like a comma expression with no effect. This implicit typing survived into C for "implicit int" return values, like "main () {...}". But type specifiers were introduced and became mandatory in declarations, and so auto became unnecessary verbiage since all it did now was specify a storage class that was already the default one. C++ resurrect the syntactic use of auto in a way: once again, it provides declaration syntax that allows the type specifier to be omitted. This time, of course, that type is inferred rather than assumed integer.
- jfoutz 8y agoThis is a great thoughtful reply to my terse, shallow comment. Thank you. It’s insightful
- shaklee3 8y agoNot the language, but some compilers have something similar: https://stackoverflow.com/questions/2053029/how-exactly-does-attribute-constructor-work https://stackoverflow.com/questions/2053029/how-exactly-does...
- Aardwolf 8y agoYep, talking about C here, not C++. If they would add that feature, you could use macros to get constructor and destructor like behavior (as long as it's within the same scope, you could write a macro that constructs your object, and in addition contains something like "at scope exit: run this function"), which would be super useful and as far as I'm aware not very complex for the compiler (as all they have to do is run some code whenever exiting scope) nor very far outside of the spirit of C (it's still very low level, just a small convenience feature with interesting implications, especially when used with macros).
- kazinator 8y agoC++ is a dialect of C. It is the result of starting with C, and then accommodating a massive, sustained sequence of feature requests, exactly like ones we are seeing in this thread. Everyone thinks that if just their pet feature request is added to C and everyone else's ideas are rejected, it will still be C.
- bunderbunder 8y agoC++ is more than that; it's a set of additional features that create something of a C-flavored multiparadigm language. Which inevitably does turn it into a kitchen sink language, since it's trying to be all things to all people. This idea doesn't seem to be in that spirit to me. It's not trying to do something radical like, say, adding OOP semantics to C. It's suggesting that C, a structured programming language, get a feature designed to improve the ergonomics for people doing structured programming in C.
- MaxBarraclough 8y agoBrief aside: Boost has a facility for doing this in C++ without declaring a new class. (It boils down to a destructor, but it's more compact.) https://www.boost.org/doc/libs/release/libs/scope_exit/doc/html/index.html https://www.boost.org/doc/libs/release/libs/scope_exit/doc/h...
- aaaaaaaaaab 8y agoBoost.ScopeExit does declare a new class via macros.
- MaxBarraclough 8y agoYes, and I hinted at this, but it's more compact.
- nwallin 8y agoDo they have a new version based on lambdas? The syntax of that is painful. I splatter my code with this: // WTFPL class Finally { std::function<void()> f; public: Finally(std::function<void()> f) : f{f} {} ~Finally() {f();} void disable() { f = [](){}; } }; Which looks much prettier: socket* s = open_socket(); // or whatever Finally cleanup_socket{[](){ close_socket(s);}}; // optionally, to keep it alive: cleanup_socket.disable(); Am typing on mobile. No guarantees about syntax errors. I still need to look into where the right places to put r value references and/or std::move are, but for the most part, I never put anything other than a pointer in the closure so I'm not worried about copy constructor cost.
- Matthias247 8y agoHowever your implementation based on std::function might allocate, which is then non-zero cost compared to normal exit statements. Better directly store the lambda inside the class, which requires that to be generic (Finally<LambdaType>). That can be hidden by using the class via a templated function which uses types interference: auto cleanup_socket = make_scope_guard([&]{ close_socket(s); }); Searching for scope_guard yields lots of alternative implementations.
- megous 8y agoYou can do it with GNU C. It would be nice if it was standard.
- kazinator 8y agoYou can do it in Bjarne Stroustrup C, which is standard. You can do it in the 20-year-old version of it, and draft versions many years before that.
- sifoobar 8y agoC++ has about as much to do with C as Java with JavaScript these days though. It's just not an option in many cases where C is fine. I've gone back and forth the last 20 years or so, and have plenty of experience with both languages. Even the experts are beginning to loose faith, it's just getting too damn complex. I'll take variants as an example, the hoops people are willing to jump through to get something as basic as unions working properly is just insane. It looks more like religion than programming from here, Rust has the same cult like behaviors going on all over the place. Edit: Ah, I see; you're more worried about them turning C into the next C++ :) I might even agree some days.
- gpderetta 8y agoPlease, C and C++ share a large subset, and, most importantly a memory model. Java and JS share, what, a couple of parentheses?
- stochastic_monk 8y agoMost C is inducted into C++ eventually. The point is that it would be nice to have something like RAII without subscribing to the full C++ perspective.
- jcelerier 8y agowell, compile with a C++ compiler and just use RAII ?
- gkfasdfasdf 8y agoYou can do this with GCC/CLang via the cleanup attribute: https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attribute... It would be nice to have this be a part of the standard.
- jws 8y agoIt's very useful. I use it for scoping the holding of locks. It replaces the idiom where you make a separate function to hold the 'when locked' code and pass all required state back and forth with nice clean inline blocks of code.
- plop_ 8y agoSomeone should submit a proposal.
- CyberDildonics 8y agoI completely agree, I think this is something that C desperately needs. D has scope(exit){...} which is similar to constructs like defer {...} Many things can be done in some form with macros and the C11 generic keyword if they have to be, but defering statements to run on scope exit is still elusive as something that can be relied upon. https://tour.dlang.org/tour/en/gems/scope-guards https://tour.dlang.org/tour/en/gems/scope-guards
- kazinator 8y agoC desperately needs to be left alone.
- dymk 8y agoYou've made a few comments like this; care to explain your thoughts rather than just say a bunch of variations on "nooooo!"?
- kazinator 8y agoThe C language is finished and great as it is. Many programmers like myself have no problem with it whatsoever. Change in a key infrastructural component like this is only destabilizing. The ISO C people should have the decency to disband and work on their pet language research projects in private.
- jononor 8y agoYou are free to stay on C89 or C99. They are not going away anytime soon, too much code relies on it.
- kazinator 8y agoIf you think if standard-driven changes to the compiler will never break your C89 code, because you're using the -std=c89 switch or whatever, you are pretty naive. The only guaranteed way your compiler won't break your code is if it's left alone.
- v_lisivka 8y ago/** * GCC and Clang extension to call cleanup function at exit * from the function with pointer to given function as argument. */ #define defer(func) __attribute__((cleanup(func))) #ifdef _CRUST_TESTS // Sample destructor, to test defer static void _tst_charp_destroy(char * * value) { if(*value) { free(*value); *value = NULL; } } // Test case it(defer, "must deallocate object at the end of the function") { defer(_tst_charp_destroy) char * s = calloc(1, sizeof(char)); (void)s; } #endif
- kazinator 8y ago> They should add something I disagree. > to run code when leaving a scope, no matter how you leave This, and various other features, were already added to C long ago. The resulting dialect was called C++.
- bunderbunder 8y agoI'm not sure I understand what you're getting at here. Are you implying that people who want new features in C should just migrate to C++ because it has even more features? Or that C is perfect as-is and anyone who wants to add new features to it should bug off to another language? Or that this particular feature is somehow equivalent to (or a slippery slope toward) adding a whole set of OOP features to C, so we might as well take that to its logical conclusion?
- kazinator 8y agoPretty much all of the above.
- bunderbunder 8y agoI'd like to hear you elaborate. You seem to be very invested in your concerns, but it's hard to understand exactly what they are. A single, clearly articulated response would do a lot more than a fusillade of terse barbs to help others understand why you think this is a bad idea.
- MrRadar 8y agoThey probably don't want to because then they'd have to specify how they would interact with the setjmp/longjmp functions (which are, in fact, specified as part of the ISO C standard, section 7.13 in C11).
- grive 8y agoThe hacks you have listed have the advantage to be visible. Reading the code, you know whether they are called or not. The issue with cleanup on scope exit is that this introduces ambiguous code-flows. You would need to demonstrate a strong advantage, beyond making life easier for the writer of the code.
- isaachier 8y agoOnce you do that, you more or less recreate C++. IMO C vs. C++ is fundamentally an issue of RAII and arguably templates. This proposal would add RAII to C.
- anticensor 8y agoYou have seem to have left C++ in 1999. C++ has expanded so much that someone can create its own operating system just by adding drivers around its standard library.