monotone-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Monotone-devel] C++11


From: Markus Wanner
Subject: Re: [Monotone-devel] C++11
Date: Tue, 13 May 2014 19:51:35 +0200
User-agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Icedove/24.4.0

Thomas,

On 05/13/2014 09:08 AM, Thomas Keller wrote:
> Since I'm not developing with C++ anymore on a daily basis, would you
> mind to give guys like me some examples / judgement why monotone should
> switch to C++11? I could think of having less code in monotone because
> more is taken care of already in the stdlib, but some examples would be
> nice.

In general, I think it's not a question of whether or not to adapt to
C++11, but when. Given we've just released 1.1 and most compilers (even
Microsofts) now offer decent support for a "new" standard that's around
three years old, I personally think now is a good time. But I'm glad to
show you some of the new C++11 features.

In the nvm.mandatory-cxx11 branch, I already replaced quite some boost
constructs, for which there now is an equivalent or better standard
C++11 counterpart. Examples: std::shared_ptr<> replaces
boost::shared_ptr<>, std::unordered_{set,map} replaces all of the former
hash_map.hh, static_assert replaces BOOST_STATIC_ASSERT, to_string
replaces lexical_cast<string>, etc...

So much of boost has vanished, that I started to check if it's feasible
to drop the boost requirement altogether (even if it's headers only).
After the obvious replacements in nvm.mandatory-cxx11, the following
boost usage remained:

 * boost/format.hpp                used by: sanity.hh
 * boost/dynamic_bitset.hpp        used by: merkle_tree.cc, ancestry.cc
 * boost/concept_check.hpp         used by: paths.hh
 * boost/multi_index_container.hpp used by: ancestry.cc
 * boost/tokenizer.hpp:            used by: rcs_import.cc, selectors.cc,
                                            migrate_schema.cc
 * boost/random.hpp                used by: tests/xdelta.cc
 * boost/lexical_cast.hpp          for lexical_casts<> to anything but
                                   string, mostly bool and ints.

Some of these seem easy enough to replace: With botan, we have at least
one other good PRNG (albeit a crypto PRNG might be overkill for testing
purposes), the multi_index_container can be replaced by multiple
standard containers in parallel and the tokenizers in use seem
relatively simple. For most lexical casts, there are C++11 std library
functions as well. Only lexical_cast<bool> would need a replacement, but
that seems easy enough.

Others look harder: The formatter is not trivial to re-implement, I
guess. I'm not sure how many of its features we really use, though.
Concepts didn't make it into C++11, so the concept_check there seems
difficult to replace. Do we really need it, though? I'm not sure how
performance critical the dynamic_bitset is and how it compares to
vector<bool> (which implementations are allowed (but not required) to
optimize into a bit vector).

There's another option: Including the headers (for the remaining
features) in our source tree. The boost license would allow that and
there's a precedent: src/boost/circular_buffer*.hpp (which Graydon
introduced more than 10 years ago, originates from Boost around ca.
release 1.30 and essentially remained untouched ever since). There
clearly are downsides to that approach: Distributors generally don't
like that, as it circumvents their tools for tracking build time
dependencies. And bugs fixed in boost wouldn't automatically propagate
to monotone, anymore (upon rebuild of the latter).


Regarding language features: There are lots! I don't think I can give a
comprehensive overview. Maybe not even a good one. However, my personal
favorite is the new move semantics: perfect forwarding, rvalues and move
constructors, which can often eliminate the need to copy. And sometimes
allow you to pass-by-value, rather than using const references.

Another feature comes in form of a keyword: 'auto'. It basically tells
the compiler to figure itself what type a variable needs to be. Not
losing type safety, but often making obvious things less redundant.
Consider this example patch for src/network/reator.cc (a combination of
the 'auto' keyword with the range based for loops feature):

> @@ -107,10 +106,9 @@ void reactor::ready(transaction_guard &
>    probe.clear();
>    lookup.clear();
>    set<shared_ptr<reactable> > todo = items;
> -  for (set<shared_ptr<reactable> >::iterator i = todo.begin();
> -       i != todo.end(); ++i)
> +  for (const auto & i : todo)
>      {
> -      ready_for_io(*i, guard);
> +      ready_for_io(i, guard);
>      }
>  }
>  bool reactor::do_io()

Nice and short. I'd certainly like to use that for places where the type
was obvious and repetitive to the human reader. However, I also think
explicitly specifying the type can sometimes be beneficial to the human
reader. So as many good things, this feature can be over-used, I think.

Another big thing are lambda functions, which can replace functors. I
don't think we use those a lot in monotone, though.

I already mentioned the static_assert above, with meaningful error
messages (as opposed to the boost variant). Also relevant to monotone:
long long is guaranteed to be an integer that's at least 64 bits long,
now (including constants).

Then there's better control of default constructors. You can explicitly
delete one or explicitly use the default one. Or delegate to another
constructor. Or inherit a base class' constructor.

And lots lots more: Initializer lists: list<pair<string, int>> = {{"A",
1}, {"B", 2}} and in-class member initializers now both work. Variadic
templates, raw string and user-defined literals, attributes, an override
keyword, etc, etc...


Bjarne Stroustrup states that C++11 feels like a new language [0]. I
personally don't think of it as new, but to me C++11 feels more like
what I always wanted C++ to feel like. I absolutely agree with his
follow-up statement: "The pieces just fit together better".

Regards

Markus Wanner


[0]: Bjarne Stroustrup's C++11 FAQ:
http://www.stroustrup.com/C++11FAQ.html#think


Attachment: signature.asc
Description: OpenPGP digital signature


reply via email to

[Prev in Thread] Current Thread [Next in Thread]