Two engineers from QuarksLab had talks accepted at CppCon this year: two tools presentation, Easy::jit, and Frozen; and a general introduction to the ELF format. It's hard to cope with the 9 hours of jet-lag, but it is definitively worth the effort, so here is our conf report!
The main challenge with CppCon lies in the balance between attending to (obviously great) technical talks, discovering new tools, chatting, going to side events, eating burgers, coping with the jet-lag and keep a decent health condition. And yes some items of this list are not compatible :-)
This is a selection of talks we attended to and somehow echoed to our personal experiences.
Plenary talk: Concepts by Bjarne Stroustrup
[Bjarne Stroustrup, abstract] [video]
High level talk « this is not a technical talk » by the language's creator on concepts, a forthcoming feature of C++ that obsoletes the use of std::enable_if and gives more semantics to template parameters.
Basically, in pre-concept C++, any function template has an implicit contract that is only checked at template-instanciation, in a very Python-ic way. It is the primary cause of the famous template error cascade C++ users are familiar with. For instance the following function
template<class T>
auto increment(T & arg) {
return ++arg;
}
holds the implict contract that operator++(T&) exists. Concepts could replace that by:
template<typename T>
concept Incrementable = requires(T& a) {
{ ++a} ;
template<Incrementable T>
auto increment(T& arg) {
return ++arg;
}
An example usage of the increment function is given in https://godbolt.org/z/zOrKym, with a surprisingly understandable error message \o/
Concerning the design of new concepts, Bjarne states that it should be possible to compose existing standard concepts, or build new ones based on expressions, but he also warns us that finding the good granularity is difficult. For instance, when one requires the + operator between two instances of the same type, is addable a good concept? Different languages have found different answers to the problem. Love how a type issue is related to a linguistic issue: when one requires an object to have the draw method, it can be any kind of shape, picture... or a cowboy :-). Thank you structural typing. An interesting remark is that auto is a kind of catch-all concept. And the final word is so true: « when it comes to new concepts, I find programmers very good at finding problems ». Kind of an occupational hazard.
Teaching C++
[Christopher Di Bella, abstract]
I rarely teach C++ to students. It's a complex language that introduces multiple paradigms, which does not make it the easiest one for students. Or so I thought, this talk and the enlightening discussion we had afterward definitively changed my mind.
The author emphasizes the need to gradually introduce stuff. For instance he proposes to only introduce int, double, std::string, std::vector, char, bool and enum class as the basic « types ». He enforces the keep your content united rule, introduce new concepts when they are needed, e.g. reference through function calls that try to modify input parameters.
Tooling is a rare place of diversity for C++, and there is no defacto standard. Providing simple skeletons for students may be of great help to start small projects. That's a very nice tip: don't spend too much time teaching them the tools, just provide them a way to use them, and focus on the language!
Some note for the « C == C++ » lovers: in C, the size of a constant char is typically equal to 4, and to 1 in C++. So they are different languages. [0]
We had a small chat afterward, and shared some anecdotes about « know-all » students. And the definitive answer is: obliterate them with more knowledge, without getting cocky :-).
Compile-time Regular Expressions
Explores the limits of performing pre-computation steps at compile time. Some humble people do that for hash-tables, but this talk is insane: building the matcher of regular expressions at compile time is definitively a funky yet useful idea. So parsing the regexp string is done at compile time, and to achieve that goal the author basically implemented a LL(1) parser using some kind of symbol <> type equivalence, and function overloads to represent transitions, carrying the actual semantic actions. In addition to initializing with 0 overhead, the engine is also very fast, which is impressive. Interesting suggestion from the audience: as the engine is built at compile-time, depending on the regexp, different engines could be chosen, if a specific engine is known to be more efficient for some patterns, e.g. for captures.
Surprise in Object Lifetime
That's the kind of talk where you're sure to learn some tricks. That's the beauty (or the failure) of C++: there's always something to learn :-) Here I learnt a lot about life-time extension, if-init, reference initialization while destructuring type... Plus Jason is a great speaker who makes his talk very interactive.
Simpler C++
[Herb Sutter, abstract] [Kate Gregory, abstract]
That's actually two talks, which showcase that, indeed, the language carries some complexity. The first one was more about code complexity as a whole. It makes a difference between simple as understood by beginners, which means don't error check, input check, test etc: concentrate on one thing at a time to reduce the « cognitive burden ». And then as real life comes in, we tend to think that everything is complex. But simple for the professional now means pleasant, reassuring and unsurprising. A very good example of reference frame switch! Very interesting note about the fact that developers rely on libraries and idioms to stay simple, that variable names (and thus <algorithm>) carry an intention, while single letters don't. Oh and I learnt the name of a game I play every now and then: « chase the const ».
The second talk is more focused on C++: a simpler C++ does not mean C++ with less things, adding features can make the language simpler if the addition makes user code simpler (as ranged for do), express intent more directly, or remove sharp edges of the language.
I also found an answer to the question « what makes a code C++ic » (or C++ish?):
zero overhead abstraction
determinism (predictability?)
link compatibility (with C)
Engage, Entertain And Educate: Technical Speaking that Works
[Andrei Alexandrescu, Kate Gregory and Scott Meyers, abstract]
As I (Juan) was a first time presenter at cppcon, I was able to attend a course before the conference on how to give technical talks. This seminar was given by Andrei Alexandrescu, Kate Gregory and Scott Meyers; with some special presenters as Herb Sutter and Bjarne Stroustrup.
Through several exercises they taught us how to start and finish a presentation, and transmit in the most effective way to the audience. With Andrei we did one exercise were we had to tell a one minute story. He stressed on how to finish the story with punch, and to be careful when sad feelings are evoked (one solution: try to change the mood just after it). According to Kate, for example, the best way to finish a presentation is to use the same phrase used to start it. With Scott we practiced in the same room as the presentation would take place in the following days, to verify possible technical issues: use the microphone, take water to the stand, the projector not working, font sizes, being asked a question (you have to repeat the question for it to be recorded in the video), etc.
It was also great to hear that Bjarne, for example, still gets nervous when presenting in front of big audiences; or how much Herb Sutter had to practice his 5 minute presentation.
What Do We Mean When We Say Nothing At All?
Some constructs carry no meaning for C++: some C++17 attributes (e.g. [[maybe_unused]] or [[fallthrough]]), for example; a return in a void function; or the name of the parameters in a function declaration. In this presentation, Kate talked about many cases were using some coding conventions consistently can help the reader of the code understand the author's intention, although they carry no meaning for the compiler and have no consequences in the generated code.
For example, sometimes, a parameter that remains unused is added to a function to match a given signature. The name of the parameters in a function declaration are optional, and many times are not specified. However, using the names consistently, and not putting the names for the ignored parameters can help the reader understand that this argument is ignored.
int Fleeve(int Schlime, int);
QuarksLab's Talks
Here are the slides from Serge:
It was nice to meet IRL some frozen commiter, and to chat with linker experts during the talk about ELF!
Here are the slides from Juan:
SCM Challenge
Once again, I had great fun with the online challenge (which is still open for those who wanna try). I only did challenge 1 and 3, here are my contributions.
The first challenge consists in finding test cases that exhibit dangling pointers and are correctly spotted by the given static analyzer. I did find test cases, but they were not spotted :-/
First test case returns a dangling reference on memory allocated in the scope of the function:
int& sum(std::vector<int> x) {
return *x.begin();
}
Second test case is also a dangling reference, using an in-place new on local storage:
int & foo() {
int x;
int * g = new (&x) int();
return *g;
}
Third case is a false positive: the push_back while iterating over the container is invalid on a std::vector but not on a list.
#include <list>
void invalidate(std::list<int>& x) {
bool first = true;
for(auto v :x ) {
if(first) {
x.push_back(v);
first = false;
}
}
}
The third challenge requires to « fill the hole » using dense modern syntax. It actually contains three sub challenges:
First a static-size array that uses either the heap or the stack:
#include <cassert>
#include <algorithm>
#include <vector>
#include <iterator>
#include <array>
#include <iostream>
template<class T, std::size_t N>
class dynarray : public std::vector<T> {
public:
dynarray() : std::vector<T>(N) {}
};
template<typename T, std::size_t N>
using buffer = typename std::conditional<(N * sizeof(T) <= 4096), std::array<T, N>, dynarray<T, N>>::type;
int main() {
using namespace std;
enum { N = 1'024 };
constexpr auto small = buffer<int, N>{};
static_assert(sizeof small == sizeof(int) * N);
assert(all_of(begin(small), end(small), [](int n) { return !n; }));
auto big = buffer<double, N>{};
assert(size(big) == N);
assert(all_of(begin(big), end(big), [](double n) { return !n; }));
}
Then a sample use of std::variant, too long to be pasted here, so it's on godbolt.
And finally some variadic + fold operator fun:
#include <iostream>
template<class T, class... Args>
constexpr T bitmask(Args... indices) {
static_assert(std::is_unsigned<T>::value, "unsigned");
static_assert(std::is_integral<T>::value, "unsigned");
return ((T(1) << indices) | ... | T(0));
}
template<class T, class... Args>
constexpr T mask(T value, Args... indices) {
return value & bitmask<T>(indices...);
}
template<class T, class... Args>
constexpr bool all_set(T value, Args... indices) {
return mask<T>(value, indices...) == bitmask<T>(indices...);
}
template<class T, class... Args>
constexpr std::size_t count_set(T value, Args... indices) {
// Kernighan's way
auto v = mask<T>(value, indices...);
std::size_t count = 0;
while(v) {
++count;
v &= (v - 1);
}
return count;
}
int main() {
static_assert(bitmask<unsigned int>(0, 1, 2) == 0x07u);
static_assert(bitmask<unsigned int>(2, 0, 1) == 0x07u);
static_assert(bitmask<unsigned int>(0, 4) == 0x11u);
static_assert(mask(0x07u, 0, 1) == 0x03u);
static_assert(mask(0x07u, 2) == 0x04u);
static_assert(all_set(0x07u, 2, 0, 1));
static_assert(all_set(0x11u, 4));
static_assert(!all_set(0x11u, 0, 8, 9));
static_assert(count_set(0x07u, 0, 1, 8) == 2);
static_assert(count_set(0x07u, 7, 8) == 0);
}
Bellevue, Washington, USA
Apart from the main events, there are plenty of stuff to do at CppCon and around: hang out in the city park, have a good run in the surroundings, take a bite of some tasty burgers, discover the Oculus rift, report bugs to the VisualStudio team, enjoy the view on the lake, taste the American version of « croissant », have a good laugh during the lightning talks...
As a final word, although goto is considered harmful, this snippet looks very good to me:
goto cppcon;
cppcon:
enjoy();
Acknowledgements
We would like to thank everybody who made CppCon such a great experience:
the conference staff, for organizing such a colossal conference: handling the accommodations for the speakers; ensuring that the microphones and projectors work; recording, editing and uploading the presentations; ensuring there always always snacks and drinks for such a crowd; creating an interesting schedule full of activities to attend, from morning to night.
the reviewers of our talks: for providing us with feedback that we could use to better target our audience and improve our talks.
Quarkslab: for funding the trip, and providing us with all the time we needed for preparing our presentations before the conference. And for motivating us to share our experiences with the community.
And of course, the Quarkslab fellows who reviewed this post o/
[0] | : see https://stackoverflow.com/questions/2172943/size-of-character-a-in-c-c |