Posted Apr 1, 2012 6:41 UTC (Sun) by Cyberax (✭ supporter ✭, #52523)
In reply to: Uses by cmccabe
Parent article: Go version 1 released
Well, I know that C++ doesn't like it when people anthropomorphize it. But it's easier than saying 'some members of C++ committee'.
Golang already shows its ugly areas - people shouldn't allow C developers to design languages. And as I've said, error handling is one of the ugly parts.
I've written a fair amount of code in Go and I've already encountered cases where changes to functions required addition of 'err' parameter, breaking my code in the process.
A some libraries now have all the functions returning Error as the second parameter in all functions, even if it's never actually used but might be used some day in future. Which is crazy.
>The only "guarantees" worth the name are those that are enforced by the compiler.
Go instead decided to make a step back - it HAS exceptions (a rose by any other name...) but they are fugly.
>If it's a programmer error, then panic. If it's anything else, return an appropriate result, whatever that may be.
That's the result of map.get('something') if map itself misbehaves?
>To do proper error handling, you need to clean up local resources. Do exceptions help with that?
YES, THEY DO!!!
In C++ exception force you to use RAII to manage resources. That ensures that resources are automatically released during the normal execution flow and simply CAN'T be leaked.
While explicit error code handling practically ensures that some cleanup actions are going to be missed. That's why the most common error handling pattern in plain C is 'goto cleanup' which essentially emulates the stack unwinding.
Posted Apr 1, 2012 23:18 UTC (Sun) by cmccabe (guest, #60281)
[Link]
> I've written a fair amount of code in Go and I've already
> encountered cases where changes to functions required
> addition of 'err' parameter, breaking my code in the process.
One of the worst APIs I've used was the original wireless.h (aka "wireless extensions") API in the Linux kernel. Basically, it forwards you a bunch of ioctls that come from userspace. Except it doesn't bother to parse them at all-- it's YOUR job to parse a giant blob of bytes, try to pick out fields, and do pointer-chasing.
When asked why this was so, the author simply replied, "if I had provided a callback API, I would have had to update all the callback implementors each time I added a new field." (I'm paraphrasing a bit; I can't find the original email.) When I read this response, I couldn't stop laughing for about a minute. Well of COURSE you have to change the callback implementors when the ioctl changes. That's the point of the type system! But he couldn't see it. Later wireless.h was replaced by the excellent nl80211 API.
I think, like him, you may be missing the point here. The point of the type system is to make guarantees. Real guarantees, not just conventions. "I will not encounter any errors" is just such a guarantee, and that's what you're promising when you don't provide an error return code.
[snip discussion of noexcept]
C++ already HAS a way of declaring that a function won't throw-- add "throw()" to the end of the function. They're going to add another way?
And apparently this new way will also just be a programmer promise with no real weight:
> This technically allowed the possibility that a noexcept function could
> still throw: this would trigger an undefined behavior. In addition,
> current exception specifications in C++03 were to be deprecated.
>
> Then, Rani Sharoni proposed a different solution... [snip]
Yeah. Sounds like progress. C++ throw specifications are FUBAR, and a change like this will just turn the pain level up to 11. You'll be dealing with two __different__ broken exception specification systems. Good luck dealing with library code that may not get updated to the new system for years!
Even if they managed to sort out this mess, they'd still just be re-inventing Java checked exceptions, which most people find verbose and annoying.
> In C++ exception force you to use RAII to manage resources. That ensures
> that resources are automatically released during the normal execution flow
> and simply CAN'T be leaked.
>
> While explicit error code handling practically ensures that some cleanup
> actions are going to be missed. That's why the most common error handling
> pattern in plain C is 'goto cleanup' which essentially emulates the stack
> unwinding.
Exceptions and RAII are two different things. For example, Google does not use exceptions, but they make heavy use of RAII. Golang also has its own version of RAII, the defer statement. And, of course, garbage collection means that there is a lot less cleanup to do.
Anyway, even Herb Sutter admits that the best exception-safe code which implements a certain algorithm may sometimes be less efficient than the best non-exception-safe code. And he's an enthusiastic advocate of exceptions. So my question to you is, if you're going to sacrifice efficiency in this way, why use a low-level, non-garbage collected, memory-unsafe language in the first place?
Uses
Posted Apr 2, 2012 14:34 UTC (Mon) by jwakely (subscriber, #60262)
[Link]
C++ already HAS a way of declaring that a function won't throw-- add "throw()" to the end of the function. They're going to add another way?
A non-empty exception spec i.e. throw(X,Y,Z) is deprecated, but you're left with (as before) throw() meaning the function won't throw or if that's not given then (as before) it means the function might throw, and could throw any type.
But in order to make throw() useful for metaprogramming there's a new way to spell it which is noexcept(true) or simply noexcept. You can also say noexcept(false) to say a function might throw, which seems useless until you realise the boolean can be any constant expression, so a function template with parameter T can be declared noexcept(is_nothrow_copyable<T>::value) i.e. the function guarantees not to throw if copying T won't throw. There is also a noexcept operator that can be used to query whether arbitrary expressions will throw.
It's not a new mechanism, it's the same one with the useless part (non-empty exception specs) removed, and more useful syntax.
If library code isn't updated to the new mechanism it doesn't matter, it still works fine (but noone should be using non-empty exception specs anyway, they're crap) and throw() is equivalent to noexcept.
Uses
Posted Apr 2, 2012 15:00 UTC (Mon) by jwakely (subscriber, #60262)
[Link]
(It's not _precisely_ the same, but the differences for most people's uses are equivalent or are an improvement anyway.)