LWN.net Logo

Uses

Uses

Posted Apr 1, 2012 23:18 UTC (Sun) by cmccabe (guest, #60281)
In reply to: Uses by Cyberax
Parent article: Go version 1 released

> 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?


(Log in to post comments)

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.)

Copyright © 2013, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds