tags:

views:

820

answers:

7

This latest Herb Sutter trip report on the C++0x standardisation process indicates that the committee has decided to completely drop the "export" concept for templates, and to deprecate exception specifications.

I think these are both good moves, but I'm interested if anyone out there has a code base where these changes will cause them sleepless nights?

+5  A: 

Certainly no sleepless nights on any of the codebases I have been involved with over the past 5-6 years. I don't think I've ever encountered anybody who used export, plus experts like Herb Sutter have been railing against exception specifications (apart from nothrow) for so long that most programmers have got the message by now.

Timo Geusch
+3  A: 

export was never implemented properly in gcc or MSVC, (but apparently was so in EDG/Comeau, as comments say), but I'd guess it never got widespread acceptance. (But I mainly live in the gcc/msvc world, so my viewpoint doesn't encompass the entire C++ community.)

As for exception specs, I believe they were broken too.

Third, deprecation doesn't mean will-cause-compiler-errors. It's just strongly suggested that user shouldn't use it and, if applicable (not so much here, I think), move on to other mechanisms to achieve the same goal.

Marcus Lindblom
`export` was implemented in EDG's frontend. Are there any indications that it wasn't implemented properly?
sbi
@Marcus, besides EDGs frontend, Comeau fully implements export.
Georg Fritzsche
someone gotta explain me how is it at all possible to implement export, without creating an intermediate pre-parsed but not compiled language which goes into object files.
Pavel Radzivilovsky
@Pavel: Comeaus manual has some details: http://www.comeaucomputing.com/4.0/docs/userman/export.html. Note that you can't avoid publication of sources with export.
Georg Fritzsche
@gf. It was my understanding that Comeau uses EDG front-end.
Nemanja Trifunovic
Thanks for the comment on export. Sorry for my ignorance. I've updated the entry.
Marcus Lindblom
The Standard at 2.1/1p8 says that one could implement export without having the source definition available by "encoding sufficient information into the translated translation unit". I suspect tho that this would be too much of an effort (and wouldn't really hide the template code anyway, it's just present in another form), so in practice export would still need the template definition code.
Johannes Schaub - litb
@litb: I'm guessing it would at best be roughly equivalent to the difference between Java source and bytecode. The "sufficient information" in the intermediate binary form corresponds to the type and name information in bytecode. It's faster to verify and load Java bytecode than to compile Java source, but if the reason you want your template source to be unavailable is to "hide" it, then the "sufficient information" makes decompilation really easy. Likewise Java obfuscators were big a few years back, because javac's output was easy to decompile. Probably still is.
Steve Jessop
@Nemanja, I didn't say anything different, did i?
Georg Fritzsche
+1  A: 

I think both moves are good and neither will cause me any pain and I like the clarification of intent with regards to noexcept.

Len Holgate
noexcept is proposed as kind of exception specification and as operator similar to decltype. The rationale can be found in http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2983.html and related papers. It solves a couple of issues including better exception safety with move operations.
sellibitze
No, I meant I like the fact that noexcept says exactly what it means rather than having to rely on an exception specification that specifies no exceptions will be thrown. It means that we can say 'exception specifications == bad AND deprecated' without any clarification about how they're sometimes useful to specify that no exceptions would be thrown. Thanks for the link though.
Len Holgate
+2  A: 

I certainly won't shed a tear over exception specification. ("A good idea which, unfortunately, never worked out.") All they ever were good for were what now noexcept stands for.

But I had hoped that export would make it. As the very least, export would allow you to change helper functions for templates without having to re-compile all the code using those templates. And it would get us rid of all those detail namespaces:

namespace detail { // actually we don't want this public, but can't avoid it
  template<typename T>
  void f_helper() { /*---*/ }
}

template<typename T>
void f() {detail::f_helper();}

void g() {f<int>();} // has to recompile if f_helper()'s implementation changes

Alas, since only one of the compilers I had to use during the last decade ever implemented it, I could never use it.

sbi
The problem with `export` is that it was hugely complex to implement, and as far as I know, the semantics weren't as useful as hoped. I've never really looked into it (since everyone always just says "do not use"), but from what I've heard and read, it wasn't as useful as it seemed. Maybe someone else can elaborate?
jalf
@jalf: I haven't used it either, but I think it depends what you mean by "useful". Some people maybe thought it would mean "I don't have to ship the source for the templates in my library, just the binaries", and were sorely disappointed. But sbi is saying, "I don't have to recompile quite so much code every time I change a template", which sounds about right to me. Of course you still have to re-link, and presumably linking exported templates is slower than linking compiled classes. So perhaps not as much of a gain as avoiding recompilation of non-template code?
Steve Jessop
@Steve and @jalf: As I said, I haven't used `export` myself, however, ISTR Daveed Vandervorde (of EDG) claiming that it does indeed reduce turnaround times because it prevents recompilations due to changes to indirectly used code as in my example. When you tinker with heavily used template code (e.g., http://www.templog.org - a logging library usually is used just about everywhere), compilation times can become a major PITA.
sbi
Yeah, in your particular example I believe you can speed up compilation in C++0x by explicitly instantiating `f_helper<int>` somewhere and referring to it in the `g()` translation unit with an `extern` declaration for that instantiation. This means `g()` always links against the other T.U, so while your build systems will still recompile it if the template changes, at least it won't have to instantiate the template, and neither will the 76 other TUs that use `f<int>`. Still fairly painful, though, requiring work *per instantiation* rather than per template.
Steve Jessop
@Steve: While that might work in my small example, it doesn't work in real projects, where you have thousands of such helpers instantiated with who-knows-what arguments. Imagine some template-meta stuff - who will go and figure out which template parameters a complex compile-time list is really instantiated with... No no, preventing indirect users of it from having to re-compile would be a very good feature that I'd like to have and that's very hard to do manually.
sbi
Unfortunately it's very hard for the compiler to do, too, hence the lack of support for `export` ;-)
Steve Jessop
A: 

I imagine that any compiler that supports them now will continue to support them for the forseeable future as optional extensions so that people can still compile their existing code.

John Burton
@JB Only if they stick with that compiler/platform.
anon
True, but hopefully it will give those most affected some time to change their code. throw shouldn't take much fixing, I guess export would but that wasn't widely implemented anyway
John Burton
Herb Sutter goes into this in some detail in the article the question links to. If your code was using `export`, then it was using EDG (the only implementation), so you could not have switched to another compiler anyway. Removing it from the standard (a) results in standard-conforming compilers other than EDG-based ones, for the first time ever; (b) allows EDG to remove it on their own schedule. All compilers must continue to support exception specifications if they're only deprecated, so the concern doesn't apply to that.
Steve Jessop
@Steve You certainly could have looked forward with some expectation of switching to another compiler - it was that kind of thing I was interested in when I asked the question.
anon
@Neil: true, but it would be a pretty vague kind of expectation. Do you know of anyone else who's even working on `export`? I'm slightly surprised Sutter didn't mention the possibility of making it an optional feature (like `int8_t`), alongside the options of deprecation and removal. If EDG is allowed to have a non-standard meaning of `export`, then somebody else could have a *different* non-standard meaning, which seems marginally less safe to me than saying "if it does anything, it does this". But maybe an optional feature is undesirable for some good reason that went without saying.
Steve Jessop
@Steve Jessop: Optional features are inherently undesirable in standards. If you write a conforming program, it should run on a conforming implementation. Given optional features, you can either not use them (in which case why are they in the standard?) or be unable to use some conforming compilers. (Yes, this is a little personal. I got bit by SQL's levels of compliance once, and I've been against options and subsets ever since.)
David Thornley
@David: true. But C++0x contains optional features already. I don't think it should go without saying that other optional features are no good. Based on Sutter's report I do see one reason optional `export` may be dismissed, which is that EDG didn't ask for it, and this part of the standard is wholly driven by EDG. That's why I'm only slightly surprised. "Why are they in the standard" - generally because some (but not all) implementations can do something desirable, and it's better for them to do exactly the same than to each define their own behaviour. This is the case with `int8_t`.
Steve Jessop
Arguably a cleaner way to do that is with a separate but non-conflicting standard, which implementations can additionally support. It amounts to the same thing, though, instead of writing a program which requires "C99, and for `int8_t` and `uint32_t` to exist", you write a program which requires "C99, ISO:blah_di_blah:8, and ISO:blah_di_blah:u32". It's just a question of who curates the standards. So for another example, IEEE is in charge of floating-point representations, and C and C++ implementations optionally implement IEEE 754 (with a preprocessor token to say so, in C99).
Steve Jessop
@Steve Jessop: I think you got why `export` was removed exactly correct.
David Thornley
+5  A: 

I've been programming in C++ since cfront 1.0, and I am happy to say I've never written an exception specification or allowed one in code that I was responsible for. When they were proposed, I called Bjarne Stroustrup on the phone and cried, "Don't do it!" I gave all the reasons why they were a horrible idea. To my surprise, he said something like, "I know." When I asked why the feature-from-Hades was going into the spec, he said there was a Big Player whose "experts" resolutely insisted that it had to go into the spec or they would absolutely not sign off, period, end of discussion. If I ever knew who it was, I've forgotten.

I've been deprecating a long time. :-)

Jive Dadson
+1  A: 

Anyone who thinks noexcept is a good idea needs to read this 3 part series. Here's part 3, the conclusion:

http://www.informit.com/guides/content.aspx?g=cplusplus&amp;seqNum=483

Leeks and Leaks
What `noexcept` is is a cut-down exception specification. If nothing else, it provides the ability to trash the whole exception specification nonsense, while keeping the only part that's actually proved possibly useful. The question is not "Should we add `noexcept` to the language?" but rather "How much of exception specifications can we get rid of?".
David Thornley