Saturday, April 1, 2017

Ibiza ISO C++ standards meeting trip report, April 2027

I've just returned from the last C++ Committee meeting in Ibiza and it was awesome! We had a very busy and productive week both in the hotel and on the beach. The Committee gets more productive by each meeting - a lot of features were included in C++Next - static destructors, overloading operatorauto, non-template template templates and template non-template templates to name a few. Multiple TSes moved forward considerably. Let me summarize some of the work we've done starting with one of the minor features.

[[figure_it_out]] attribute

This was voted into the C++Next and I'm very proud of it because I personally proposed it. You can read the full proposal here. This is basically telling the compiler to deduce what the function should do based on the function name. For example:
template <class T>
[[figure_it_out]] auto multiply(const T&, const T&);
This serves as both declaration and definition - the compiler should be able to deduce that this should multiply the two input parameters. This builds on top of the hugely successful Intelligent Q&A Compiler TS where for example if you forgot to add the fifth closing bracket the compiler will ask you: "Did you forgot a closing bracket here? Should I add it because it will be faster?". Most of you remember that this capability was partly enabled after the Committee acknowledged that AIs have advanced enough and allowed the compiler to modify the compiled code under strict conditions (no more "expected ';' after class definition" errors!) Initially only after receiving a confirmation from the user but soon it was realized that the users answer Yes 95% of the time so now this is pretty much automatic.

Also if you write:
[[figure_it_out]] std::string DownloadFileFromTheInternet(const std::string& url);
expect the compiler to ask you "Where to download the file: in the temp folder or in the app folder?" or something similar before it implements the proper stuff to download the file from the Internet. Do not forget - the questions asked by the compiler are unspecified.

The intent of this feature is to be able to write more maintainable, understandable and self-explanatory code. Of course, this attribute has limitations - it can not work with nameless lambdas or functions named DoTheJob(), ImplementFacebook(), etc. Let's not ask the impossible from the compiler.

Pseudocode proposal

With the Committee finally acknowledging the obvious - hardware is cheap, energy is cheap, software developers time is expensive - this proposal made substantial progress. We all know the best and fastest way to generate source code is to paste it from the Internet. With so many algorithms described in pseudo code using them will be easier than ever. So for example if you want to paste bubble sort pseudocode from Wikipedia it is now possible to do it:
template<Sortable container>
void MySort( container& A)
{
_pseudocode  {
    n = length(A)
        repeat
            swapped = false
            for i = 1 to n-1 inclusive do
                /* if this pair is out of order */
                if A[i-1] > A[i] then
                     /* swap them and remember something changed */
                     swap( A[i-1], A[i] )
                     swapped = true
                end if
            end for
        until not swapped
  }
}
But you may expect in such case the compiler to ask you: "Are you trying to implement a bubble sort? Why don't you use std::sort instead?". The proposal is designed to work with all popular programming languages and other types of pseudocode. We hope to vote it into TS at the next meeting.

Other proposals made progress too:

Social Compiler - designed to fill the soft skills gap in the C++ developers' community. The compiler is now able to small-talk with you about the weather for example or to remind you of that time when you two finally managed to compile that nasty template instantiation.. aah good times! Or find you friends based on the files you recently compiled. This functionality is implemented for several years as a language extension and the results are very promising - there are reports of couples successfully hooked up by the compiler and some of them even having kids! How cool is that? This builds on top of Personalized Compiler TS that hugely improved the errors reported by the compiler by personalizing them to be better understandable by the owner of the compiler. This is done by analyzing data mined from type style, typing speed, time it takes to comprehend an error, analysis of the audio input when the user encounters errors (intonation, swearing, crying, etc) and other unspecified input.

We fixed some bugs in Brain link TS it is based on boost::brain_link this offers portable API for linking human brain with the computer and downloading or uploading stuff. Unlike Boost the Committee decided to standardize only the human brain linking but not the pleiad of sub-libraries for animals - boost::brain_link::cats, etc. Now you are able to write your own dreams downloading programs and review if that cool and revolutionary idea you just had in your dream [but forgot] is really that cool or is something like "the water is wet".

Teleport semantics - using virtual quantum entanglement to teleport objects. However, we have problems counting the votes on this one because the Committee members are finding it very funny to act like qubits and claim they've voted for and against at the same time. All those "Observing my vote is changing my state so it does not count" jokes...

Metareflections - reflecting about reflections. Are you reflecting enough? This helps answer this question among other things.

Sadly, The Committee did not allow the compilers themselves to attend the meetings -  to vote on proposals and to make proposals. Which is unfortunate because we know for a fact that many of the proposals nowadays come from the personalized compilers although the human authors will never admit they took credit for the hard work the AIs are doing. Boost heavily exploits compiler proposed library additions nowadays. boost::brain_link::aardvark, yea, sure - human wrote that. Anyway. You should probably expect a lot of bitching from your compiler to not be as polite as usual in the next couple of months: "You know this would have compiled if aI was allowed to propose stuff!" or "It compiles with 0 errors but we have to tolerate this sub-optimality because you humans are sooo 2019!".

Nevertheless!

Very exciting times for C++!!! The future is brighter than ever!!!

Thursday, March 23, 2017

C++ tips, 2017 Week 9 (27-Feb - 5-Mar-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you don't have it in your company start it. 
List of all weekly posts can be found here.


1. std::accumulate

std::accumulate is a fundamental STL algorithm that uses operator+ on the elements of a range or  applies a custom provided operator:

Thursday, March 16, 2017

C++ tips, 2017 Week 8 (20-Feb - 26-Feb-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you don't have it in your company start it. 
List of all weekly posts can be found here.

1. bitset

std::bitset is a container for bits. Unlike the infamous std::vector<bool> it size is set at compile time so bitsets with different sizes are different types. It is designed to replace C-style more-<<,>>,|,&-than-program-expressions storing of binary flags in a long for example. It has operator[], bound checking tests, evaluating if all, none or any of the bits are true. It can also count the bits set to true so if are asked during an interview "How to count the true bits in a sequence of chars?" you can show the depth of your STL knowledge by answering something like "Well first I'll use std::bitset::count to write the most readable solution, then use it for baseline and then use std::array<char, 256> with precomputed number of bits for each index"

Monday, March 6, 2017

C++ tips, 2017 Week 7 (13-Feb - 19-Feb-2017)


This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you don't have it in your company start it. 
List of all weekly posts can be found here.

1. Behavior

The C++ Standard defines several levels of behaviors that one should be aware of. If the program is well-formed (it follows the Standard syntax and compiles):
  • Specified - well... as the name suggests you can expect things to happen exactly as described in the Standard
  • Implementation defined - the Standard describes the outcome but how the input will be transformed into the output is up to the implementers. This is why for example
    std::map implementations differ between compiler vendors - it's up to them how to implement it.
  • Unspecified - Similar to implementation defined but the Committee intentionally left it undocumented. It is well-formed but you as a C++ user should not care exactly what it is. Take the returned type of std::bind for example. You can create a variable from what std::bind returns using auto and you can wrap it in std::functions type-erasing it but what it is exactly should not concern you.
  • Undefined behavior - a.k.a. the mother of all confusion. Basically, means that you should not make assumptions about what will happen in an undefined behavior situation and plan accordingly. It is usually for a reason - often we do not want to enforce too strict requirements on behavior [that introduce unnecessary functionality or disable compiler optimizations]. I think of it as an extreme variant of "don't pay for what you don't use". Reading from uninitialized local variables, for example, is UB. Yes, the Standard could have required all variables to be default initialized but that is often unnecessary and forces the compiler to default initialize them thus reducing the performance.

Saturday, February 25, 2017

C++ User Group Sofia first year

Some time in November 2015 we decided that it is a shame that we do not have a C++ User Group in Sofia, Bulgaria, and we decided that instead of waiting to just make it. This is a retro and an overview of what happened in our first year. I hope you find it helpful and inspirational.

A year or two earlier I began to realize that I'm a dark matter developer and I started to read more articles, created dedicated dev twitter account, started listening to podcasts (thank you, CppCast!) - it was kind of waking up experience. When you plug into the C++ news stream you begin to realize that our community is currently flourishing and expanding. As the community grows there is need for more face to face communication -  nothing replaces face to face communication. Probably realizing that Jens Weller, a.k.a. Meeting C++, started to encourage and help creating C++ User Groups.

Monday, February 20, 2017

C++ tips, 2017 Week 6 (6-Feb - 12-Feb-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.

1. Trailing return type

In C++11 we got trailing return type. That is we can write the return type at the end:


reason for this was lambdas with multiple return statements and function templates that that have return type dependent on the input parameter types:


however from C++14 we have Generalized return type deduction and now in most of the cases you can omit writing the trailing return type and just use auto.

Friday, February 10, 2017

C++ tips, 2017 Week 5 (30-Jan - 5-Feb-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.

1. std::size, data, empty

From C++17 we are getting the free functions std::size, std::data, std::empty. They are similar to the free functions std::begin and std::end and if used with standard container just call the corresponding member function and work for C-style arrays if it makes sense. Possible std::size implementation for C-style arrays (container one just returns .size()):

(lets try GitHub Gist because Blogger formatting is driving me nuts)

Thursday, February 2, 2017

C++ tips, 2017 Week 4 (23-Jan - 29-Jan-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.


1. .front() and .back()

The sequence containers from STL have these two functions for accessing the first or the last element of the container (or an analogue like std::priority_queue::top). They do not return iterator but a reference to the object in the vector.

We've all seen code like this:
std::vector<SomeElement> elements;

// later

SomeElement element;
// some calculations and initializations involving the element
// possibly passing it around by reference
elements.push_back(element);
//or
elements.emplace_back(std::move(element));
This is where .back() comes handy - instead of creating local variable and than inserting into the container sometimes it is better to insert it first and than work directly with the inserted object getting access to it by using back/front/top/etc:
elements.emplace_back();
auto& element = elements.back();

// same calculations and initializations involving the element
// possibly passing it around by reference
This is applicable in the simpler cases and there is no need to involve copy/move semantics.

Thursday, January 26, 2017

C++ tips, 2017 Week 3 (16-Jan - 22-Jan-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.

1. std::is_trivially_copyable

std::is_trivially_copyable tests a type (or a C-style array) if its a TriviallyCopyable type. In short this means if you can and you are allowed to just memcpy one object into another. "If you can" (obviously you can memcpy everything but...) means that the type does not have virtual member function, virtual base class or any non-trivial (user provided) copy/move operations or destructor. Providing any user defined copy/move operation or destructor signals the compiler that there is something special about this type and it should avoid some optimizations. "You are allowed" means that at least one move/copy operations is not deleted and the destructor is not deleted too.

Thursday, January 19, 2017

C++ tips, 2017 Week 2 (9-Jan - 15-Jan-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.


1. std::forward

std::forward helps ... forward a T&& function argument as-is to another function. In the following example:
template<class T>
void choose_foo(T&& arg)
{
   foo(arg);
}
arg is treated as lvalue and will call the T& overload of foo. However if we pass a temporary to choose_foo we probably want to call the T&& overload of foo (if any). To fix this we use std::forward:
template<class T>
void choose_foo(T&& u)
{
   foo(std::forward<T>(u));
}

Wednesday, January 11, 2017

C++ tips, 2017 Week 1 (2-Jan - 8-Jan-2017)

This is part of my weekly C++ posts based on the daily C++ tips I make at my work. I strongly recommend this practice. If you dont have it in your company start it. 
List of all weekly posts can be found here.


1. No raw  loops

If you have watched Sean Parent's great talk C++ seasoning you know the goal No raw loop (if you haven't - go and watch it). In short - always try to not use raw loops.

The rationale behind this is simple. When you are using raw loops you are usually iterating over something. Most likely it will be a container. Most likely it will be a std or boost container in which case you are going to use iterators. And since you are doing something while iterating over the container with those iterators it is most likely something already implemented in the <algorithm> library - either being finding, for_each-ing, merging, copying, sorting, filtering, etc.