Earlier quoted context omitted.
> To eschew exceptions almost always entails giving up RAII How so? RAII works just fine when you return errors.
How about in constructors?
Memory management in C programs (2014)
31–40 of 106 posts
Re: Memory management in C programs (2014)
#32I'm going to claim that the problem being solved here fundamentally comes from attempting to shoehorn early exit into an ancient codebase that wasn't designed for it, via longjmp. Exceptions can be a handy language feature, but plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without them. It just has to be written so that most functions manually propagate…
> plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without [exceptions]. I would not consider C++ code that eschews exceptions "modern". To eschew exceptions almost always entails giving up RAII, and if you give up RAII you've done yourself a huge disservice: you're now stuck manually managing memory and resources, and suffering all the bugs that come with…
This is especially true when third party code is involved. C++ is hard enough to get right without exceptions; dealing with failure in bodies of code that you didn't write and maybe don't have control over (or even source code of) is death on wheels.
If that means the code I'm working on isn't modern . . . I think that's fine. But the first volume (of three?) of Herb Sutter's Exceptional C++ should be enough to convince anyone that dealing with exceptions "correctly" is time better spent eschewing exceptions and restructuring your code so you can do worthwhile hard things.
Re: Memory management in C programs (2014)
#33I'm going to claim that the problem being solved here fundamentally comes from attempting to shoehorn early exit into an ancient codebase that wasn't designed for it, via longjmp. Exceptions can be a handy language feature, but plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without them. It just has to be written so that most functions manually propagate…
Completely agree, and it's surprising to see this in Nethack because game programmers almost unanimously shun exceptions. In games, you have a small number of functions that can tolerate failure, probably relating to IO. Everything else instantly explodes.
Re: Memory management in C programs (2014)
#34Earlier quoted context omitted.
> To eschew exceptions almost always entails giving up RAII How so? RAII works just fine when you return errors.
How about in constructors?
Note: I don't actually know C++ very well. It's possible there's a more idiomatic way to accomplish this. In particular, another wrapper class could be created that owns an instance of the trivially-constructed instance mentioned above. The factory function could then take an instance of the wrapper class and then modify and return an instance of the class you actually want to obtain.
Re: Memory management in C programs (2014)
#35Earlier quoted context omitted.
How about in constructors?
Init methods is the answer to that (but it potentially forces some additional complexity around initialized/not-initialized state into the other methods).
http://250bpm.com/blog:4 >
Re: Memory management in C programs (2014)
#36I'm going to claim that the problem being solved here fundamentally comes from attempting to shoehorn early exit into an ancient codebase that wasn't designed for it, via longjmp. Exceptions can be a handy language feature, but plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without them. It just has to be written so that most functions manually propagate…
> plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without [exceptions]. I would not consider C++ code that eschews exceptions "modern". To eschew exceptions almost always entails giving up RAII, and if you give up RAII you've done yourself a huge disservice: you're now stuck manually managing memory and resources, and suffering all the bugs that come with…
Re: Memory management in C programs (2014)
#37As someone obsessed with writing C code, something just clicked. I think I understand better why there are so many JavaScript programmers, so many tools and frameworks written in and around JS every day. For me, C is the gateway to the computer. It's ubiquitous. It's deceptively simple. I can literally write anything I want in C. It's an exciting thing to have an open main.c file sitting in front of me. That must be…
As a non-C user, C was always too forboding. I wrote a bit of it, and read K&R, but places like HN bang into your head that you'll likely make a horrible screw-up writing C, your code won't be secure, and it's better not to bother. Maybe I should spend some more time with it.
Re: Memory management in C programs (2014)
#38Earlier quoted context omitted.
> plenty of modern code written in languages like C++ (whose exception support is often eschewed) and Go gets by without [exceptions]. I would not consider C++ code that eschews exceptions "modern". To eschew exceptions almost always entails giving up RAII, and if you give up RAII you've done yourself a huge disservice: you're now stuck manually managing memory and resources, and suffering all the bugs that come with…
I've not seen a large production C++ code base that did anything with exceptions other than to catch them, record some debug information and restart. This is especially true when third party code is involved. C++ is hard enough to get right without exceptions; dealing with failure in bodies of code that you didn't write and maybe don't have control over (or even source code of) is death on wheels. If that means the c…
In what manner? If you use exceptions, you must (IMO) use RAII, or yes, it will be painful. Every example of "painful C++" I've seen involved someone ignoring that, and that is fighting the language. I understand that's a bit of a strawman argument, but you didn't elaborate enough in your post to debate it.
If you are using RAII, exceptions shouldn't be terribly hard to "get right"; an exception propagating up the stack will free resources as it goes. (This is the same behavior, again, as numerous other languages; except in C++, I have the benefit of RAII, in others, I generally do not.)
> dealing with failure in bodies of code that you didn't write and maybe don't have control over (or even source code of) is death on wheels.
It's peculiar that I only ever hear this argument against C++, when Python, C#, and to an extent Java¹ work in the same manner. Were you writing a C++ webserver, for example, I expect that you would do exactly what my current job's Python webserver does: if an uncaught exception makes it to the main request handler, it is caught in a catch-all, duly logged, and a 500 served in response. This is appropriate both in Python and C++ IMO. (Whereas in the hypothetical C++ side, I gain the benefits of static typing and RAII that I can never have in Python.)
In my day-to-day Python, we quite often learn about uncaught exceptions — from third-party code that I didn't write and maybe don't have control over — in production; sometimes, we will add a handler for that particular exception where appropriate (it was a bug) or fix the underlying symptom (the exception indicates a larger problem, and allowing it to propagate to a good catch-all point was appropriate, as was 500'ing the request).
But again, "death on wheels" is not really something I can provide worthwhile argument against. Perhaps where third-party code has caused pain (at least, for me) is when a very low level (say, socket error) propagates through the stack; there might not be a good way to catch these beyond "catch everything", but again, that's not unique to C++. The biggest problem I've had with these is that they lack context: what caused this socket error? Or, if some library catches & re-throws its own exception class, too often do they discard the inner error, and I lack the root cause (a different lack of context). But you see this in Python as well. Error codes are perhaps the worst, as they will quite often force you to lose context; do you expose error codes for all of your inner error conditions? (And theirs, transitively?). (I've never seen a non-exception C++ or a C codebase use anything aside from error codes as a substitute.)
Re: Memory management in C programs (2014)
#39As someone obsessed with writing C code, something just clicked. I think I understand better why there are so many JavaScript programmers, so many tools and frameworks written in and around JS every day. For me, C is the gateway to the computer. It's ubiquitous. It's deceptively simple. I can literally write anything I want in C. It's an exciting thing to have an open main.c file sitting in front of me. That must be…
And above us is probably FORTRAN and above them is probably COBOL. Actually, I think assembly language would probably be the next age "peak". If you know Asm you'll be far better at C; things like pointers and indirection immediately make sense. The effect is weaker, but still there in the other direction. (FYI, FORTRAN predates COBOL by a few years.)
A lot of recent issues with compilers "introducing security issues" has come from this sort of understanding of C (overflows, other undefined behavior, etc). The places where C differs from just writing the assembly yourself are really really hard.
Re: Memory management in C programs (2014)
#40Earlier quoted context omitted.
How about in constructors?
Init methods is the answer to that (but it potentially forces some additional complexity around initialized/not-initialized state into the other methods).
At least in C++ (and many other OO languages), I find the downsides of having these Jekyll and Hyde classes outweigh any benefits that may come of ignoring exceptions.