BlogGSOC: C++2011 Support in KDevelop Part 1 Syndicate content

Tue, 06/28/2011 - 14:09

Hey all,

I finally want to write a bit about my work on KDevelop during this year’s GSOC. To make things a bit more interesting for the whole crowd, even for those heretics that don’t use KDevelop, I want to highlight some C++2011 features I got to know in the process. Hence this multipart blog post should be interesting for all KDE hackers, as eventually we will be able to use these shiny new features of what is to be known as C++2011.

For those interested in the full overview of changes in C++2011, take a look at e.g. the C++0x Status Page in GCC 4.6, the wikipedia article on C++0x, or try to get hold of a copy of the C++2011 FDIS spec file. Note that the latter is apparently not freely accessible, see also this stackoverflow discussion. Still, maybe you find someone who can send you a copy…

So, lets get down to business. Following is a not-complete list of C++2011 features I’ve already implemented in KDevelop. If I mess something up in explaining a new feature, or if I forget an important aspect, please add a comment.

Range-Based for

This neat little addition is not so important to most Qt developers. We know and love our foreach macro. C++2011 comes with a similar built-in construct called range-based for. Essentially the syntax goes like this:

  1. QVector<MyType> list;
  2. for(const MyType& item : list) {
  3. // do stuff
  4. }

It’s neat, and very similar in syntax to the oldschool foreach macro. But there is a big difference: Where foreach makes a copy of the container, range-based for does not. This has mainly two implications:

  1. foreach is slow when used with containers that don’t use implicit sharing, most prominently STL containers
  2. range-based for has undefined behavior when you change the list you iterate over inside the loop.

Personally, I think I’ll stick to the foreach macro as it’s known to work well and has no big downsides in most Qt-based applications, as implicit-sharing is widely used throughout Qt.

RValue References / Move Support

This feature is a more advanced topic and mainly interesting for library developers who want to implement move semantics and/or achieve perfect forwarding, resulting in much better performance under certain conditions. Take a look at the Brief Introduction to RValue References, or the associated spec changes. From the syntax POV it’s just a matter of using && for rvalue references compared to the single & for normal lvalue references.

Defaulted and Deleted functions

This addition to the C++ spec is very welcome to me as it makes some code much more readable and also can be used to prevent hard-to-debug bugs or to improve performance. I’m talking about defaulted and deleted functions. E.g. from the wikipedia article:

  1. struct NonCopyable {
  2. NonCopyable & operator=(const NonCopyable&) = delete;
  3. NonCopyable(const NonCopyable&) = delete;
  4. NonCopyable() = default;
  5. };
  6. struct NoInt {
  7. void f(double i);
  8. void f(int) = delete;
  9. };

This shows the syntax of how to use this new feature. The advantages:

  • You can explicitly mark functions as deleted: Before you had to move these functions into private section of a class and not provide an implementation. When (accidentally) trying to use such a function you used to get unintuitive compile or linker errors. Now you get a nice message about usage of an explicitly deleted function.
  • You can prevent unwanted conversions: Using deleted functions is also useful when you want to prevent some function to be called with a different type that can be implicitly converted to your function’s wanted argument type.
  • Performance with defaulted functions: Compilers tend to write highly optimized code where possible. Implicitly defined constructors or assignment operators e.g. are one of these cases. But as soon as you use inheritance you (mostly) cannot use the implicit versions. Thanks to the new defaulted functions you can do that again. Furthermore it’s possible to change the access policy of an implicitly defined function (which are usually public) using the default syntax.
Variadic Templates

I confess that this is one of the more esoteric features of C++2011 for me. I never really did any serious template meta programming, and variadic templates are just as complicated as the other template programming. Yet I do see the advantages if people start to use it.

Anyhow, I implemented the required parser changes into KDevelop, but proper code completion and DUChain integration might need some time and brain effort :)

static_assert

Now back to simpler things, yet definitely welcome and useful ones. One example are static assertions, i.e. compile-time assertions. The document I linked to contains a list of examples which should show how useful this feature is. Note that we Qt-users know and love the Q_ASSERT macro, but it is a runtime check. Boost users have had a BOOST_STATIC_ASSERT macro for some time, now we will finally be able to use it as well.

STL updates

Ah, before I forget it: Since KDevelop parses the STL includes, you should be able to use all new STL features already. If you spot a serious parser error in one of the include files of GCC 4.6 or 4.7, please notify me.

much much more

These are only some of the new features which I’ve added support for in KDevelop. I’ll try to sit down later today to write part 2, otherwise I’ll do that after I come back from the Fusion festival next week. Anyways, you can stay tuned for features like constexpr, opaque-enum-declarations, class-enums, improved right-shift token handling in nested templates, etc. pp.

Comments

“Performance with defaulted Wed, 06/29/2011 - 20:32 — Ville Voutilainen (not verified)

“Performance with defaulted functions: Compilers tend to write highly optimized code where possible. Implicitly defined constructors or assignment operators e.g. are one of these cases. But as soon as you use inheritance you (mostly) cannot use the implicit versions. Thanks to the new defaulted functions you can do that again.”

I do wonder what you mean by that. If an implicitly generated special member function can’t work with inheritance in some cases (and I’d like to see an example of what that’s supposed to mean), I don’t see how a defaulted special member function would work any better.

That’s what I remember from Mon, 07/04/2011 - 15:45 — Milian Wolff

That’s what I remember from the stuff I read, but indeed I can’t find something suitable to cite - so take it with a grain of salt. Note though that at least the virtual dtor can now be defaulted and hence optimized - something which was not possible before as the implicit version was never virtual. Same/similar with other methods probably.

Nice. :) What is about Tue, 06/28/2011 - 17:15 — The User (not verified)

Nice. :) What is about type-inference? (auto, decltype, typeof) Such a typesafe printf could be implemented before, too, but you would have needed tuples with such pre-generated code for simple tuple-generation, but for the user it would have looked the same with 100x compile time. ;) The printf-link is broken (add http://).

link fixed, and changed the Tue, 06/28/2011 - 18:27 — Milian Wolff

link fixed, and changed the text a bit. thanks

re type-inference: auto is partially supported (and has been, for some time). decltype needs implementation. But I have not come across typeof in c++0x, nor can I find it in the C++ FDIS spec.

It is a GNU extension and it Tue, 06/28/2011 - 23:22 — The User (not verified)

It is a GNU extension and it has been in the parser for long time (but not correctly interpreted I think), there is a small difference, like stripping qualifiers or something like that, not sure. If you will implement decltype you would probably just have to add some very similar lines to finish the typeof-support.

Some time I filed a bug about Wed, 06/29/2011 - 11:28 — thorGT (not verified)

Some time I filed a bug about typeof. IIRC, it is still ignored by the parser and causes errors. So it’s a well known bug. :)

No, it is handled by the Wed, 06/29/2011 - 15:53 — The User (not verified)

No, it is handled by the parser and the lexer, but no semantics implemented.

small correction: “This Tue, 06/28/2011 - 15:23 — illissius (not verified)

small correction:

“This feature is a more advanced topic and mainly interesting for library developers who want to implement move semantics to achieve perfect forwarding”

Rvalue references allow you to write move constructors and also to implement ‘perfect forwarding’, but these are two completely separate things.

thanks, changed “to” to Tue, 06/28/2011 - 16:47 — Milian Wolff

thanks, changed “to” to “and/or” :)

Post new comment

The content of this field is kept private and will not be shown publicly.
  • You can use Markdown syntax to format and style the text. Also see Markdown Extra for tables, footnotes, and more.
  • You can enable syntax highlighting of source code with the following tags: <code>, <blockcode>, <pre>.
  • Web page addresses and e-mail addresses turn into links automatically.

More information about formatting options