Thursday 17 October 2013

How does C++11 bugfixing in C++14 look like?


Maybe you've heard it already, but the planned C++14 standard will be a small, bugfixing release for the C++11 specification and not a true next version of C++.

Well, not really (see here), there are a couple of interesting genuine new features added! For example: generic lambdas (yay! see my old post...), lambda capture initialization expressions, function return type deduction (i.e. auto on functions), templates for variables, runtime-sized arrays (int arr[varX]), binary literals (011100b), shared mutexes and locks, std::optional, standard user-defined literals (like "xxx"s for std::string), std::dynarray, tuple access via type (get<int>(tupleX)). I don't know what you think, but for me that's quite a list of new features (and that's not a complete list) to be digested!

But some of the changes are real bugfixes. For myself, I couldn't imagine what bugfixing could be supposed to mean - are there bugs in the standard? With best C++ gurus working on that? Well, unfortunately there are! One of them is the absence of std::make_unique() counterpart to the std::make_shared(). What is is the reason for that? Herb Sutter explains:
" That C++11 doesn’t include make_unique is partly an oversight, and it will almost certainly be added in the future. "
 What, an oversight! But beacuse of that you cannot write a safe code for multiple resource initialization using std::unique_ptr! That (and hearing them speaking on Going Native 2013) convinces me that the gurus are just humans and developers like you and me!

Another case in point is taken from a discussion on complex initialization idiom. Here's the code:
  const int i = [&]{
    int i = some_default_value;
    if(someConditionIstrue)
    { 
      // Do some operations and calculate the value of i;
      i = some calculated value;
    }
    return i;
  } () // note: () invokes the lambda!

Well, it looks absolutely innocuous (and kind of JavaScript like!), and it will even compile. But Andrzej Krzemieński pointed out that:
I believe it is not a valid C++11 code. According to sect 5.1.2 para 4, when the body of the lambda is not a simple return statement its deduced return type is void. While the expectation that this example would work is logical, and likely acceptable in C++14, C++11 seems to refuse it.
And you know what? Herb explains:
The committee has already pretty much agreed that this should be allowed (which is why our compiler also already supports it, and with GCC and Clang that would make it de facto portable), and this extension is likely to be voted into the C++ working paper soon (this month, or September).
Thus making it a classic example of bugfixing! Well, not really, the standard says that lambda return type can be deduced, but only when there is exactly one statement, and that statement is a return statement that returns an expression. OK, but compilers can do much more than that already, so it's an unnecessary restriction we can do away with! Thus in this case it's not really an oversight, but rather lack of time to process feedback from compiler writers. Bjarne was always saying that the committee is doing unpaid work and that mostly in their free time.

Update:

Ooops, I forgot that std::optional and std::dynarray were moved out of the standard and parked in TS.  Thanks for correction goes to @meetingcpp!

2 comments:

Anonymous said...

Wasn't std::optional voted out?

Marek Krj said...

well, yes, I forgot about that TS business. Thanks, but I corrected it already!