“Searching for another overload”: overloading and replacing new and delete with MSVC v142

A brief history of Total War

The Total War codebase has been maturing for a little over twenty years now, and is starting to resemble a very fine, rich port. Shogun: Total War and Medieval: Total War were released on version 1, Rome: Total War and Medieval 2: Total War were released on version 2. Having got the hang of things by then, we moved to version 3. The new architectural approach of TW3 has kept us going since Empire: Total War, released in 2009.

By the time we reached this title we started to run into a problem. A strange error appeared, 0xC0000017 STATUS_NO_MEMORY (Not Enough Quota). It happened on all machines, regardless of the amount of RAM installed on the motherboard. I researched, and discovered that we had a finite amount of address space available to us. A 32-bit Windows process has 4GB of addressable storage, but half of that is reserved to the OS. We only had 2GB available to us. A little more digging around revealed to us that we could get another 1GB if we tweaked the OS environment and selected /LARGEADDRESSAWARE in the linker options, but it was not appropriate to ask users to make that kind of adjustment. Our players are a bright bunch, but we decided this was too much. We had to constrain and control our address space usage. Suddenly, we were overloading operator new.

Object storage duration

Object storage duration and linkage is a significant matter in C++. I usually include a question about it in interviews. You can read about it at cppreference.com. Running out of storage means that you need to store fewer things, make the things you are storing smaller, or both. I know this sounds obvious, but it bears stating unambiguously. The total amount of data in a Total War game far exceeds 2GB. Nearly all the data is stored offline on a file system, added into the process when needed, and removed from the process when no longer required. However, “store fewer things” is easy to say and hard to do.
Consider automatic storage duration objects. These are kept on the stack. Making significant changes would require introducing tracking to every scope, which although feasible requires additional per-function code, much like exception handling. Anyway, the stack is already accounted for by the linker. It is allocated as part of the thread and although you can change the size of the stack in your linker options, it isn’t advisable. Filling and emptying it won’t change the amount of storage available to you, so it’s not worth pursuing savings in this storage class.
static and thread storage duration objects are a different matter. We can identify those by searching for the keywords static and thread_local. Unfortunately, this won’t catch ALL the static storage duration objects: anything defined at file scope has static storage duration. In addition to polluting the global namespace, this is another reason not to define objects at file scope but at anonymous namespace scope instead. They will still have static storage duration, but they will be easier to find.
Empire: Total War was made before C++11 was published, so we were making no use of thread storage duration objects. We had only a small number of static storage duration objects. This left us with reducing dynamic storage duration objects.

Managing objects

Recall how objects are managed. Some address space is found, an object is constructed into that space, the object does its object thing, the object is destroyed, and the address space is returned.
For automatic storage duration objects finding and returning memory is simply a matter of increasing and decreasing the stack pointer. Once the stack pointer gets too large, for example during recursion that goes too deep, no more storage of that class is available.
For static storage duration objects, the storage is found at the start of execution and returned at the end of execution. Static objects are created at startup, more precisely at static-init (except for static objects with function scope: they are created as their owning functions invoked) and destroyed at exit during static-deinit. For thread-local storage duration objects the story is similar, except that the storage is found as part of the creation and destruction of the thread. You could consider static-init and static-deinit as being the creation and destruction of the main thread.
For dynamic storage duration objects, the storage is found by calling operator new and returned by calling operator delete. This happens during the invocation of the new operator and the delete operator. I’ll rephrase that: the new operator calls operator new and then the constructor of the object being created, while the delete operator calls the destructor of the object being destroyed and then operator delete. Differentiate between the new operator and operator new, and the delete operator and operator delete. Indeed, if you look at std::allocator_traits, you will see four important member functions, allocate, construct, destroy and deallocate.

Overloading operator new

There are rather a lot of operator new functions; the standard defines 22, 14 of which are non-member functions. How does the new operator know which operator new to call? It does so by considering the parameters passed to it. Ordinarily, there will be no parameters. You would simply write
auto t = new T(args);
The first parameter is implicit: the amount of storage to allocate. This would call operator new(std::size_t). If you already have an address p to put the object, you can write
auto t = new(p) T(args);
This would call operator new(std::size_t, void*).
As I said earlier: “Suddenly, we were overloading operator new”. We did this by declaring an overload of operator new and defining it inline to call our own function, ca_malloc, which was declared in our own namespace, which, as you may be able to guess, is CA for Creative Assembly. Our overload contained the filename and line number, so the signature looked like
void* operator new(std::size_t, const char*, int);
To invoke this, we had to replace every call to new with new(__FILE__, __LINE__). Then we realised that the release version of the game should call regular operator new, so we needed to replace our new invocations with a preprocessor macro. I first saw this trick in MFC in the early 90s.
After overloading operator delete to call ca_free, we could take a look at our allocation patterns. Not only that, we could see which objects were being released long after they were needed, or never released at all. This last category is a memory leak. Memory leaks are A Bad Thing as they consume resources for the remainder of the process. We got rid of our memory leaks, tracked them ferociously, named and shamed programmers who leaked resources, and kept track of everything. According to our accounting, we were well inside the 2GB limit. However, we were STILL running out of storage.

Accounting for overhead

Unfortunately, allocating 24 bytes doesn’t reduce your available storage by a mere 24 bytes: there is book-keeping to consider as well. The memory manager has to keep track of what is available and what is in use. This all takes additional storage, and the more allocations you have, the more storage you require to keep track of it all. We were unable to reduce the amount of objects we had and the storage they might require, which meant that we had to reduce the overhead by writing a better memory manager and invoking that instead.
This is not a trivial undertaking. However, operator new is a worst case scenario memory manager: it is a single function that knows nothing about how long something is needed for, nor how big anything is going to be. We knew a little more about our objects than the memory manager, and I wrote a series of memory managers to take advantage of this.
The first was the fixed-size memory manager. If you know that you’re going to be allocating lots of objects that are 24 bytes big, you can keep a big slab of memory to accommodate them all in consecutive slots. You can use a large bitfield to track which slots are occupied and which aren’t, and use the address of the allocation to identify which slot it came from.
Then there was the LIFO memory manager. If you know that you’re going to be creating things and destroying them in reverse order, then you don’t need to track anything at all. You can simply use some storage to accommodate them and create your own pointer to the next free space. This will point back and forth through the storage as items are created and destroyed. This is useful for traversing UI, which tends to embody a tree structure going forward and backwards along branches.
Next was the frame memory manager. If you know the upper limit of the capacity of a container, and you know it’s duration is within a particular stack frame, you can create an allocator on the stack before the container, and then pass that allocator to the container. This allows you to use automatic storage instead of dynamic storage, providing an instant win.
A variation of this was the duration memory manager. If you have a family of objects that you know are going to exist only within a particular frame, you can create a general purpose memory manager in automatic storage and ensure that all allocations made by this family of objects go through that memory manager. You can also check that there are no outstanding allocations when it is destroyed and eliminate memory leaks.

Replacing operator new

So far I have spoken about overloading operator new. By typing new(some parameters) you can customise your allocation. But what about containers? How do you overload their memory managers?
Recall that the standard containers all take an allocator parameter, which dictates how memory will be managed. You can simply replace the default parameter, std::allocator, with your own allocator, which defines the functions of std::allocator_traits as described earlier.
How about third-party code? What if you are using a third-party header only library that uses standard containers with default allocators? What if it makes direct calls to new? Then you have to REPLACE operator new.
This was easy enough in the Total War codebase. By defining void* operator new(size_t) as an inline function the compiler was able to resolve the call immediately, so no linkage was required. This replaced the implementation of operator new located in the C++ runtime library by not requiring the linker to search for it.
Unfortunately, the story doesn’t end there. If you grab a copy of the standard at wg21.link and look for [replacement.functions] (it’s a big PDF, have patience) you will see that it’s not so easy. Particularly, regarding replacement functions,
The program’s declarations shall not be specified as inline. No diagnostic is required.
This was news to me when I upgraded the Total War codebase to support the v142 MSVC toolset. Suddenly, I got a new warning telling me that I couldn’t declare operator new inline. This was rather a change from no diagnostic required. We have a zero warnings policy (/W4 /WX) so I was required to address it.
I’ve been using the Microsoft C and C++ compiler since 1989 (I think). It has been quite permissive. For example, if a function takes a reference to a non-const object, for a long time I could simply create a temporary at the call site. Strictly speaking, this is only permissible for a function that takes a reference to a const object. There are several other examples, such as two phase lookup, which have been tightened up over recent years. Now it was the turn of inline replacement of operator new.
I didn’t worry: the Total War codebase has a foundation library that everything links to. I defined the functions there and hit build, sauntering over to the kitchen to make a pot of Earl Grey tea. On my return I was greeted with a raft of linker errors, telling me that operator new(size_t) was multiply defined in my foundation library and, of course, in the C++ runtime library.

Linker shenanigans

The standard has very, very little to say about linkers. I was now in implementation-defined territory, relying on what I knew about the toolset and its history. The first thing I did was look at the command line, where I saw all the library inputs, some object files, and a batch of innocuous looking command line options, which I carefully examined nonetheless.
There didn’t appear to be anything in any documentation outlining how to replace operator new. There was no linker magic referred to. I switched the /VERBOSE flag on and examined the tens of thousands of lines of output. Clear as day, there was operator new, imported from the C++ runtime library.
I decided some experimentation was in order. I wanted to be absolutely sure that the command line was the only place that any library dependencies were being declared so that I could see if the library declaration order was significant. This was not trivial. There are three ways to tell the linker what libraries to search.
  1. The command line – the most obvious way
  2. Importing dependents – declaring in the project properties that a project is dependent on another
  3. #pragma comment(lib, <library name>) – the most insidious of all
Methods one and two are quite benign. You can explicitly say “look in hat.lib” by simply appending hat.lib to the command line, just as you do with object files. Importing project dependencies is reflected immediately in the command line as well. Method three is completely invisible. It plants a comment in the object file which signals the linker to find and import a library.
This has its advantages. By including a header for a third party library, you can automatically add a library to your imports and not have to worry about adding it to your command line. This is especially important if there are several versions (NDEBUG, _ITERATOR_DEBUG_LEVEL=2 and so on) and you don’t want to have to remember all the incantations. For example, when you add /MT to your compiler command line the correct comment is added depending on whether DEBUG is defined (static library, release version).
Unfortunately it obscures the logic by which it was imported, requiring you to spelunk your way through a pile of #include files. Fortunately there is a linker command to ignore these directives, /NODEFAULTLIB. Ordinarily you would use it to turn off explicit libraries, for example /NODEFAULTLIB:libcmtd, but if you simply pass it unqualified to the command line, all #pragma comment(lib) directives will be ignored.
I was now able to explicitly craft my command line, but it didn’t help. I needed to include the C++ runtime, and I needed to include my replacement operator new. Worse, sometimes I could get projects to link, while other situations would report failure, without apparent rhyme or reason. It seemed to be that if I put the C++ runtime as the last argument on the list, projects would generally link successfully, but it was not a guarantee.

Ask the implementers

I admitted defeat and asked the folk who work on the toolset for help. One advantage of attending committee meetings is that I get to meet these people, so I knew how to direct my request. I got a very enlightening response.
The new behaviour of warning about inline specification of replacement operator new was requested by the MSVC standard library developers, as such definitions can sometimes cause surprising behaviour. For example, imagine you accidentally define two replacements in the same project, perhaps one that does logging and one that does fixed-size allocation. When they are not specified as inline there is a redefinition error when you try to link. Conversely, when they are specified as inline then that is a violation of the One Definition Rule and the linker will pick one and discard the other. You might be expecting some allocations to be frame-allocated, but instead they would all be logged. Good luck debugging that.
The apparently non-deterministic linker behaviour for accepting replacement new and delete is a little more convoluted and deeply linker specific. This explanation is unique to the MSVC v142 toolset, so assume nothing about other implementations.
Firstly, of course it isn’t non-deterministic. Here are two considerations:
  1. Everything provided to the linker command line as an object file is opened, those symbols which are defined and referenced are retrieved, and then the libraries provided on the command line will be searched to resolve any remaining symbols.
  2. All libraries passed to the linker are equal. There is no preference given to user-provided libraries over implementation provided libraries. This includes the OS as well as the standard runtime. They are all equal.
Once all the explicit object files have been considered, the object files within the libraries on the command line are searched for remaining unresolved symbols. If such a symbol can be satisfied by an object file in a library, the entire object file is imported into the image. The linker will use the first such definition it finds, and it will not complain if more than one library could satisfy that definition: any others are simply ignored. However, once the linker has decided on an object file to include, it will ensure that no duplicates will be introduced, since the object file could also include definitions of other symbols that already exist, in addition to the symbol it was searching for.
This library resolution stage is recursive, since including an object file from a library can also bring in new undefined symbols, but this doesn’t mean that the search is restarted from the beginning of the command line. In fact, this algorithm is very complex, the result of many years of refinement, in order to reduce average link times.
As a result, including a replacement operator new definition in a library can be problematic, and the appropriate solution is to include your definition as an object file on your linker command line. Also, if you’re going to replace one operator new/delete pair, replace them all: you don’t want to find you’re suddenly changing to an array-new and returning to the standard library allocator without realising it. You’ll find them in the [replacement.functions] section mentioned earlier.

In conclusion

Although Total War has moved to 64-bit, we still need to track storage. It’s unlikely we will run out of address space, but our users are likely to run out of RAM. This is actually a harder problem, since different users have different RAM on their systems. Correctly overloading and replacing operators new and delete is a simple task but requires a steady hand at link time. I hope you have a clearer idea about how (and why) to do this: please ask questions in the comments.
I would like to thank Jonathan Emmett and YongKang Zhu from Microsoft for help and review in the preparation of this blog post.
“Searching for another overload” is a line from everyone’s favourite Glen Campbell song. Be advised that Wichita is 500 miles from Denver, where CppCon will be taking place shortly. I’ll see you there.

The German tour: Cologne trip report

No time for fripperies

This trip report is a little different: not only did I attend the C++ Standard committee in Cologne, but I went on to speak at the Munich C++ meetup on the following Monday. 

I arrived a day late: I rolled up on Tuesday afternoon, so I only saw a little over three days of discussion, plus the closing plenary. Still, there was plenty to cram in, including two full days of discussion of papers I’m involved with. I’m now co-authoring three active papers: the 2D graphics proposal, the audio proposal and the linear algebra proposal. Things are getting rather busy! 

There was very little time for exploring Cologne, unfortunately. The square outside the hotel was the social hub after the day’s business was completed, but that was about as far as I got. I enjoyed some German food, including a Pork Knuckle (if I translated the German correctly) that was the size of my head, as well as a variety of beers. When in Rome… 

pork_knuckle

Committee rooms

There were an astonishing 200+ people in attendance this time: many thanks and congratulations to the hosts and sponsors for accommodating us all! The order of business for this week was making sure the working draft of the next standard was completed and that a committee draft could be published. This is the version that the committee asks the National Bodies to vote on. 

Things were very busy in those rooms where wording was being finalisedthe Core Working Group for the language portion of the standard, and the Library Working Group for the library portion of the standard. However, new material is still being prepared for the standard that won’t make C++20, particularly the contents of my paper. I spent time with the Library Evolution Working Group looking at some of these new items when I wasn’t working on my Munich talk or assisting the defence of my own papers. 

The big news though was the withdrawal of Contracts from the working draft. The consensus is that it simply isn’t ready yet, and since it is a LOT harder to remove something from the standard than it is to add something, the best plan is to wait until it’s ready and keep examining it. A new Study Group has been formed, chaired by John Spicer, SG21, Contracts. I’m pretty disappointed about postponing contracts, but then again, I probably wasn’t going to get what I was expecting. I think that was possibly the general experience for many observers… 

Wednesday: 2D graphics

Two Study Groups wanted to review the graphics proposal. The first was SG16, Unicode, on Wednesday. The graphics proposal has two new features: we now support text, as well as command lists for batch processing. Text support means that the Unicode people are interested. 

Unicode interests me in general, since I find the idea of trying to describe and standardise the complete set of glyphs we as a species use to communicate with one another in absentia an extraordinary endeavour. The actual work of this is formidable and I am very impressed by Tom Honermann’s desire to chair this group and make C++ text handling more realistic. 

At the moment the 2D graphics text interface takes a std::string. The question at hand was “why not take a char8_t?” Recall that there are several character types available now: char, wchar_t, char16_t, char32_t and, if the committee draft is published without national body comment opposing this, char8_t. These last three are for UTF encoding, and it would seem obvious to take a char8_t string. However, the target of the graphics proposal is NOT the International Standard, it is a Technical Specification. Such a document must be based on a published standard, so we cannot take a char8_t until we decide to rebase the proposal on C++20. 

It seems very likely that we will do this, and we will consider our options regarding the nice new features that the language introduces. I imagine we will indeed offer char8_t support for our text: a poll was taken among the attendees and there was unanimous consent for this course of action. Interestingly, there was no support at all for offering char16_t, char32_t or wchar_t support. I’m looking forward to how text is going to pan out, and I think this SG is grappling with the hard problems. Many thanks for their time reviewing our proposal! 

Thursday: 2D graphics

On Thursday morning I was joined by my colleague from the rendering team at Creative Assembly, Dmytro Shchukin. He joined me in SG13, IO, who also wanted to take a look at the 2D graphics proposal as well as the other graphics proposal, web_view. 

This proposal, by Hal Finkel, offers a mechanism for talking directly to browsers, leveraging the enormous amount of work already put into standardising many parts of the browser ecosystem. The idea is to compose and send text strings to the browser and let it do all the rendering work. It’s a neat idea, although adding it to the standard is going to be a possibly more formidable task than the existing graphics proposal since the W3C standardisation process is rather different from the ISO process. However, Nvidia support this proposal (to my surprise, and to the astonishment of my colleague!) so it may yet make it into the standard. Further work was encouraged, and it was noted that this proposal could also cover some of the proposed audio effort (more on that later).

Discussion of the 2D Graphics proposal centred around feedback from Apple. Their experts kindly reviewed the proposal last year and provided a lot of detailed feedback which Michael McLaughlin incorporated into the proposal. We also raised issues about threading, batching, renderers, and of course how it might proceed through Library Evolution given that last time it was voted down. Although there is National Body support for this effort, the wrong design will not pass, nor should it. 

If you want to participate, look at the repository, make pull requests, raise issues, you know the drill. Mike is busy completing a Qt backend to support the text API: stay tuned. 

(also, if you have any ideas about user input, the final part of the puzzle, we are all ears) 

Friday: Linear Algebra

Friday saw a joint meeting between SG6, Numerics, SG14, Low Latency, and SG19, Machine Learning to talk about Linear Algebra. This proposal has taken off dramatically, spawning a lot of interest and several succession papers. I was only able to attend the morning sessions but work to date on the proposal was well received. 

Of particular interest was the proposal to add a free-function linear algebra library based on BLAS. This would coexist beautifully with the existing proposal, allowing implementers to use these functions to implement the proposed linear algebra library. Of course, implementers would be free to provide multiple implementations if their target platform had special support, for example DirectXMath on Windows. 

The next order of business for these proposals is to ensure they can coexist and then to present them to the Library Evolution Working Group. Indeed, this was a condition of support for forwarding. I shall start writing wording for the final paper over the next few months prior to the Autumn meeting of the committee in Belfast. 

Bob Steagall has been doing sterling work on this: please visit the repo and raise issues, try your own implementation of the operations, and give it a thorough going-over. 

Friday: Audio

I had to leave the Linear Algebra session to visit SG13 for my final paper of interest, the Audio proposal. I was delighted to note that we were in the room named Bad Homburg: this town is twinned with Exeter, the place of my birth

bad_homburg

Just as with the 2D graphics proposal, Apple gave some excellent feedback which we have largely addressed in the current proposal, and we spent time reviewing this. Sophia Poirier presented Apple’s response and there was discussion of some quite fine details, such as connecting and unplugging hardware while the process is running, deciding how to access the data and implications of contiguity, what can be handled via class and function templates and what via virtual dispatch. 

I have been taking an organisational role in this proposal rather than a direct authorial role. Timur Doumler has been leading development with Guy Somberg providing Windows expertise and additional game dev perspective. I have great interest in audio: I’ve been playing the piano for nearly 50 years now, I’m very interested in studio production and audio software, as is my son, and I’m keen to see a single low-level audio solution in the standard. There is SUCH a lot of repetition, as with 2D graphics, in existing libraries, that it is surely the time for the library to embrace IO. 

Again, check the repo, kick the tyres, play some tunes. Also, be advised that we intend to submit this to Boost.

Saturday: Closing plenary and on to Munich

As I said at the top, we succeeded in voting for publication of the Committee Draft. 

Closing plenary was a slightly strange affair since there was no room large enough to hold us all. The adjacent room received a live video stream of the proceedings, complete with jokes repeated through the microphone by the chair, John Spicer. 

There were some procedural shenanigans with a late paper billed as a bug fix, but the implementers present unanimously declared that it was NOT a bug fix. There was considerable celebration for publication, and I left with the feeling of a job well done. 

I would have liked to have seen more of Cologne, but instead I prepared my slides for the Munich meetup. Indeed, almost the entire remainder of the day was devoted to producing slides. I inadvertently bought a first-class train ticket from Cologne to Munich and enjoyed 300Km/h rail travel through Germany. Every time I looked up from my laptop there was something splendid to look at. I’m more used to UK rail travel, which is why I was particularly astonished to be served wine at my table.

wine_on_dbahn

I checked into Hotel Europa and carried on with my slides. Perhaps I spent too much time on them… 

My wife joined me on Sunday morning for a couple of days touring Munich. It’s a lovely town, and that part of the world is quite gorgeous.

img_1982

Eventually though, I had to give my talk to the Munich C++ meetup. My topic was about teaching geometry to C++. It’s the next step after linear algebra. I will be giving this talk in St Petersburg at C++ Russia at the end of October, which will be published on YouTube. Watch the skies!

img_1983

Many thanks, as always, to the C++ Foundation for sponsoring my attendance, and to the various hosts along the way. I had a great time and I’m looking forward to continuing the work in Belfast.

Telescopes and matrices and audio: Kona trip report

A little “me” time

It really does take quite a long time to traverse ten time zones. From Heathrow to Kona via Seattle is quite a trial in an aeroplane, no matter how luxurious. I attended the Kona C++ committee meeting through the benevolence of a private sponsor on the committee and the C++ foundation and, since I was going to be making the journey anyway, I decided to take a few extra days before the committee started to get over some fierce jet lag and look at the island.

I hired a car and over two days drove right around the island, visiting black sand beaches, the Southernmost point of the United States and the Mauna Kea visitor centre: ascending the summit to see the telescopes requires a 4×4 vehicle.

Of course, I wasn’t going to let that stop me and, on Sunday, with a few other committee members, I hired a 4×4 and we ascended Mauna Kea. It is a climb of 4200 metres, which we managed in about two hours, all the while worrying about altitude-sickness-induced recklessness. The drive is challenging, with some rather precipitous drops to gaze over as you slowly climb. It is an other-worldly place, above the clouds and coloured like a Martian landscape. We had to keep stopping so that we could go “wow!” at the extraordinary scenery and take photos.

As we stopped and parked among the telescopes, wandering from building to building, we realised that there was probably plenty of C++ code executing behind the doors of the observatories. We are never far from our trade.

During the descent I seemed to lose my voice, through shouting how amazing it all was at everyone in the car, and also my hearing, as I failed to equalise the pressure in my head. It seems that America and I may not be destined to enjoy harmonious times together (see Jacksonville). Nonetheless, I enjoyed the universes’s sense of irony that, in the week I would be discussing an audio paper, I was deprived of my sound I/O faculties.

Committee rooms

This was the final meeting for advancing new features to C++20. Proposals advanced to Core and Library from this meeting would be put in the wording queue with the hope of being reviewed and moved to the standard before publication. There is already an excellent report on reddit summarising the work by Bryce Adelstein Lelbach and others, so I won’t duplicate that here.

I wasn’t at the committee meeting in San Diego, so I was unfamiliar with the new Study Groups EWG-I and LEWG-I, the incubators for language evolution and library evolution. I spent most of my time in LEWG and LEWG-I considering what was trying to make its way into the C++ standard library.

I really enjoyed my time in LEWG-I. Proposals were brought for direction review or design review, and experienced library people kicked the metaphorical tyres and offered extensive advice. I imagine this will improve the process in LEWG as many obvious kinks will have been ironed out before proposals reach that point. Of course, this won’t speed up the wording review process in LWG: this doesn’t per se increase our paper bandwidth.

One of the first papers I saw in LEWG-I was P1433, Hana Dusíková’s proposal for Compile Time Regular Expressions (CTRE). Hana has been speaking about this at conferences since CppCon 2017. I am really looking forward to seeing this progress to the library, and volunteered to assist with the paper. LEWG-I also assisted with review on the two papers I am co-authoring: more details below.

Given how close we were to the deadline, I was expecting an abundance of caution from LEWG in voting stuff on to LWG in case it was a little undercooked, but perhaps I was being optimistic. The desire to get a feature into C++20 rather than waiting for another cycle (THREE WHOLE YEARS! NEARLY A LIFETIME!) may have tempered any hesitancy. There is also a new place to be careful, and that is with concepts. Once a concept is voted in, it can’t be changed: code that relies on a concept can’t have that contract narrowed or widened. Concepts are both constraining and satisfying.

Linear algebra

With two papers in flight, I didn’t spend as much time in committee rooms as usual. The first of these was P1385, a proposal to add linear algebra support to the C++ standard library. I have spoken about this at Meeting C++, an Avast meetup and C++ On Sea. This proposal has its origins in the 2D Graphics proposal: after presenting that at Jacksonville in 2018 to a somewhat hostile audience, Bob Steagall approached me to suggest that we collaborate on a separate linear algebra proposal; this is the result.

On day two of committee, an evening session was held to present the paper to interested parties. On day three we had a session in LEWG-I where we received some first class feedback from other authors of linear algebra libraries, mathematicians and engineers. On the morning of day five, SG6, SG14 and SG19 gave it a good look in a joint session. My co-author did all the talking as my voice was still in a rather broken state. It was quite dizzying but very gratifying to hear so much support for the idea and approach. In a nutshell, the proposal offers some client types (matrix, row_vector, column_vector) and a large selection of customisation options to enable the creation of the optimum specialisation for your use-case. Do read the paper: we are open to all feedback. Take a look at the straw man implementation on Bob’s repository. Star it if you like it.

I was astonished at the level of interest. Although as a mathematician it is obvious to me how fundamentally important it is for C++ to know about linear algebra, I was not expecting so many people to follow the paper so keenly. I hope that this will simply be the first of many papers. Succession papers may specialise the interface for domains like machine learning, geometry and so on. By laying the foundation, by way of providing fundamental types, I hope that linear algebra users will be able to easily write code that is comprehensible by all C++ programmers.

Audio

At the end of 2017 I watched a CppCon video by Guy Somberg about audio. Guy is a significant contributor to game audio programming, and at the end of his talk he wondered if there was scope for std::audio. I approached him via email and we started discussion over monthly teleconferences. I also asked Timur Doumler to give a non-game perspective, and we spent much of 2018 putting it together. I’ve taken a more organisational role with this paper, having found two people with considerably greater expertise than mine, but nonetheless our aims are aligned: to provide a way to record and playback audio in a standard fashion.

We first presented our efforts at ADC in November 2018 to a warm reception (note that I am at PEAK BEARD at this point, so forgive the appearance of a mad wizard; note also that the first time we met in real life was ten minutes prior to the start of this talk). This encouraged us in our efforts and we were pleased to present P1386 to the committee, particularly to LEWG-I and SG13. Impressively, Timur defended the paper almost single-handed for four hours. Again, we received some first class feedback, particularly from JF Bastien and Jeffrey Yasskin amongst others. We hope to have something significant to present at the next committee at Cologne as a result. The advance of coroutines actually simplifies things considerably, as does mdspan. Meanwhile, you can take a look at the implementation on our repository. Star it if you like it. Also, take a look at Timur’s trip report for some additional detail.

Bryce has done a great job of chairing LEWG-I and I want to thank him for the time he allocated to our papers. The quality of design input can’t be overstated and it makes a tremendous difference to our trajectory. I strongly recommend that if you have a library paper you target LEWG-I before you target LEWG.

HMI (Human-Machine Interface)

There is an overarching concern running through these papers. Devoted readers will recall that after Rapperswil an unconventional direction was chosen to continue the development of the 2D Graphics proposal. Since then, I wrote another paper defending the proposal, as a result of which SG13 was reanimated to consider the proposal, saving the committee from dealing with an external TS.

Note that SG13 is devoted to HMI, not just 2D graphics. The group’s remit is to consider all proposals related to user interaction, which means we are looking for work on audio and controllers as well.

This is a thorny subject for the committee. There are those who think the standard library should be as small as possible, while others (such as myself) have a more maximalist approach. Getting beyond the console, std::cout and std::cin, is a steep learning curve, and a standard HMI approach would help in this matter. Of course, standardising something as stable as recording and playing audio, as well as collecting controller input and returning haptic feedback, is a rather different undertaking from attempting to standardise 2D I/O.

There seems to be a division between server and client developers. Developers working on the server side don’t care for HMI, while developers on the client side live or die by good HMI. I do wonder how this circle might be squared in the coming years. With the large feature drop for C++20 out of the way, I hope that some consideration will be given to this matter during the next cycle.

What’s next

Proposals that made it through the evolution groups aren’t guaranteed to be present in C++20, since the wording review takes time, of which we have a finite amount. The next meeting in Cologne is going to be important for seeing what can be processed from that queue, and for confirming the content of the next standard.

However, we now have a pretty good idea of what C++20 will look like, and it looks like being the biggest change to the language since C++11. I imagine it won’t be long before people start saying C++2.0 and I wouldn’t blame them: since C++17 we have added concepts, contracts, ranges, coroutines and modules. These will all change the way we write C++, and change what C++ looks like. I’m particularly looking forward to seeing how coroutines will change how we read code.

My prediction for the next cycle is that it will be dominated by reflection, metaclasses, executors and networking. However, I also hope that we will start to consider the HMI question. Additionally, audio requires me to redouble my efforts to reanimate the ring buffer proposal, P0059.

I’ll be speaking about Linear Algebra at Using C++ in Madrid on Thursday March 7th, and also at 4Developers in Warsaw on Monday April 8th. I’ll also be at ACCU in Bristol from Wednesday April 10th. Stop me and ask about HMI!

Would you like me to speak at your event?

If you would like me to speak at your event, I would be delighted so to do, but I do have a few guidelines:

  • Your event must welcome everyone, no matter where they come from, nor the status of their protected characteristics.
  • You must have a Code of Conduct and an assistance team. I can help you choose and adopt one; The Berlin Code of Conduct is a good place to start: indeed, you can adopt it unamended. I can also advise on convening an assistance team.
  • If you record my talk, the video should be accessible without charge to everyone and may not be sold in any capacity.
  • I will not provide my talk materials in advance (unless there are live translations, for example to sign language or to a non-English spoken language). I will offer my slides and code examples for you to share after my talk.
  • I may present from my own laptop (HDMI from MacBook Pro) using my own slide template. Reformatting my slides to a new template is a lot of work.
  • You must cover travel expenses and conference admission.

I will prioritise events that:

  • record and publish the talk,
  • pay for business class travel arrangements or offer an honorarium,
  • make a significant and observable effort to promote diversity, such as offering reduced-rate admissions or working with groups such as #include <C++> to raise funds for travel expenses of under-represented attendees, or offering signing interpreters.
  • are held somewhere easily accessible from London Gatwick (LGW) airport,
  • include community-focused content such as lightning talks, open sessions, and panel discussions with audience questions.

Do keep in mind that:

  • I can give more than one talk if you want to maximise your budget.
  • I will be happy to mentor other speakers.
  • My schedule starts to fill from about six months in advance

Right now, I’m talking about:

  • New features for C++23 (particularly linear algebra and audio)
  • Growing better programmers by mentoring your mentors (keynote)
  • Inclusion and diversity in the C++ community

Of course, I am happy to speak on almost any topic you think I can effectively deliver to your audience.

(With thanks to Kate Gregory for her original template)

The 2D Graphics TS

The story so far

The ISO C++ committee (WG21) did not reach consensus to pursue a 2D Graphics Technical Specification (TS) during the Rapperswil session. At the end of the week the British Standards Institute (BSI) C++ panel met for its pre-plenary caucus. This is where the panel decides what position to adopt so that the delegation lead can vote in the plenary meeting on proposals that aren’t unanimously supported, as happened with the coroutines proposal.

During the caucus, disappointment was expressed about the end of the graphics effort: the BSI C++ panel was very keen for adoption of some form of drawing library into the International Standard (IS). A long serving member pointed out that we could in fact publish our own TS, and we decided to discuss this at our next meeting, which took place on July 9th.

Wait, what?

The ISO is a federation of national bodies, of which the BSI is one. Over a dozen national bodies participate in the C++ standardisation effort. Any body can publish a TS. Indeed, the BSI has published many TSes in other standardisation efforts, but never in the C++ subject.

A C++ TS is not part of the C++ IS. Particularly, from British Standard zero:

BS 0:2016, section 3.45

A TS is a document published by ISO, IEC, CEN or CENELEC about which there is the possibility of future approval as a standard, but for which at present there are reasons precluding immediate publication as a standard.

NOTE Typically the reasons for this would be that the required support for such approval cannot be obtained; there is doubt on whether consensus has been achieved or the subject matter is still under technical development.

This TS would be developed, reviewed and published independently of WG21. There is expertise within the BSI C++ panel competent to complete this work: there are experienced wording reviewers and implementers.

The BSI C++ panel post-Rapperswil meeting

Among other matters, we discussed the idea of publishing and unanimously resolved to propose a new work item for the publication of a 2D Graphics TS based on P0267.

This is new territory for the panel, and possibly for WG21. We still have to work out the process and cannot yet publish a timetable. However, what we will deliver will be wording sufficient for implementers, if they so choose, to implement the 2D Graphics library specified by the TS.

There is already a reference implementation and sample code for Windows, Linux, OS X and iOS. Emscripten support is in development. You can take a look, download and build it by visiting io2d.org. We expect to add it to the vcpkg package manager very soon which will simplify access. You can also take a look at the current version of the TS: be warned, it is nearly 200 pages long.

FAQs

Why do this if WG21 is not interested?

The work to date is very valuable. It contains the result of extensive feedback from the WG21 committee and can act as a beacon to others.

Consensus is a fluid thing, as is the makeup of the committee: there was very strong consensus for several years to pursue 2D graphics and it would be foolish to believe the current consensus will remain forever. Even if another approach is pursued, the TS will offer a starting point.

There is still demand for a standard drawing library. Many of the national bodies were as dismayed as the BSI C++ panel by the new consensus. By publishing a TS this library remains a visible candidate.

Why not try standardising another library?

The proposal is the result of many thousands of hours of work from a small number of wording experts and graphics experts. Starting again from scratch on something else would delay the introduction of 2D graphics by years. However, if you would like to undertake such a thing, I’m happy to answer questions.

It is often overlooked that having a great idea is only the very start of the standardisation process. Developing the API is a small part of the job when compared against generating the unambiguous wording for the IS document.

Won’t this fork the language?

This is not a language feature. The library is currently defined in the std::experimental namespace and will be migrated to the bsi namespace.

Won’t package management solve this?

Sadly, no. Adding the implementation to vcpkg gets this library into the hands of all those who are permitted to use third party code. However, this is by no means a universal privilege. Many commercial, industrial, governmental, financial, medical and military code shops simply outlaw third-party code, even Boost, allowing only what is provided by the compiler vendor.

The phrase “dark matter developer” refers to those developers who simply don’t engage with the rest of the community: they are invisible, observed only by the effect they have on compiler sales. Often, these are developers who are denied access to the work of the community. In my opinion it would be worth trying to find out how big this non-community membership is. Last year’s C++ survey was self-selecting from community participants: maybe it is time to commission some professional research. We ignore these developers at our peril. If we do not serve them they may migrate to other languages.

Should WG21 decide to standardise package management in such a way as to overcome this barrier, perhaps with a “blessed” repository, then the TS will be in a strong position to seed such a library.

How can I help?

We welcome any and all assistance. You can:

  1. Write some samples or tutorials
  2. Propose text or input APIs
  3. Develop a new implementation

Samples and tutorials are the easiest way to help. That’s how everyone learns to use a new feature.

We are thinking about text and input a lot of the time. It’s hard. One of the team is a long-term contributor to SDL and has some ideas, but it’s good to have more to choose from.

The current implementations are software reference implementations, using Cairo or CoreGraphics. Perhaps you could write a DirectX, Vulkan, OpenGL, Metal or nv_path_rendering implementation. They don’t need to be perfectly optimised: they only need to demonstrate feasibility. If you run into trouble, you might be highlighting a fault in the design.

You can also contact your national body and your favourite compiler vendor and ask them to support the effort. Remember, you’re the customer. Look for details of these organisations on the ISO C++ web site.

Post script

This is a post about governance more than about C++. If there are any errors or if anything is unclear, please add a comment below and I will correct or clarify as soon as possible.

I recorded a podcast with the good folk of CppCast about this and other topics. You can find it here. Many thanks to Rob and Jason for the opportunity.

2D or not 2D: that is the question: Rapperswil trip report

Beautiful Rapperswil

The summer 2018 ISO C++ committee meeting took place in Rapperswil, apparently something of a favourite with the members. Being a short flight from my home I was able to arrive on Sunday afternoon, ready to start on Monday without fear of jet-lag. The last time I was in Switzerland was by accident when I went Interrailing in 1989. It was good to return and see what state my German is in.

I shared a flight to Zurich with several committee members as it turned out, including convenor Herb Sutter. Thinking I would be able to be very  helpful with my schoolboy German, I was surprised to discover Herb has very good German. He is a man full of surprises. We shared a taxi to Rapperswil (thanks Microsoft!) and I excitedly demonstrated the latest samples written with the 2D Graphics library on my iPhone.

My expectations for this meeting were centred around what seemed like a do-or-die defence of the 2D Graphics proposal, P0267, against the Diet Graphics proposal, P1062, during the evening session of day four, Thursday. I presented the paper to the C++FRUG in Paris a week earlier, and had decided that my course of action was to polish and reduce the content while reviewing proposals in LEWG and LWG. The absence of the lead author Michael McLaughlin was a considerable handicap for me but I was determined to represent the work to the best of my abilities.

Rapperswil is gorgeous. I checked in to Hotel Jakob, as did two of the co-authors of P1062, and took a long walk around the town. It’s located on a beautiful lake, surrounded by mountainous terrain; everything was clean and neat and tidy, even the light industrial units I strolled past. I decided this was going to be a delightful week.

Carrying on where I left off

The P1062 co-authors joined me for breakfast. Professionalism is of the utmost importance and actually there’s more to life than opinions, beliefs and papers. The opening plenary commenced at 09:00 at Hochschule für Technik Rapperswil (HSR), our hosts for this meeting. Peter Sommerlad is a professor of software engineering at HSR and leads the Institute For Software, and started by ensuring we were all wearing rather fetching scarlet baseball caps, decorated with the white cross of the Swiss flag surrounded by a C and a +.

C++ Swiss Flag style
C++ Swiss Flag style

This committee was large: there were over 150 experts in attendance, and the introductions took over ten minutes. After rules and administration were covered, I went straight to LWG to carry on where I left off.

To advance the 2D paper I need to be better at writing wording; in Jacksonville I wanted to spend plenty of time in LWG just learning what the wording concerns are, but fell ill. I still feel there is plenty to learn, and spent the next two sessions of the day in LWG soaking up the process. I could feel my imposter syndrome fading as I understood what was going on with the papers: it’s hard to put into words, but the same sort of concerns appear time and again, and I was starting to be able to see them before they reached discussion in the group. We adopted quite a few papers that day.

During the fourth session I worked on my presentation. The Paris version ran for about an hour, and it’s not reasonable to spend that long talking to people at an evening session. I reviewed what could be culled and what was important, before seeking out a pizza dinner with colleagues. The weather had been gorgeous all day while we were closeted in our meeting rooms, but suddenly turned stormy in the evening.

This time last year, at my first committee, there was a session on terse/natural/simple syntax for Concepts. This is an addition to Concepts syntax, and doesn’t hold up the rest of the TS. This continues to be an unresolved problem and there were two presentations, one by Herb and one by Bjarne, presenting two different options. The session stretched out beyond three hours, at the end of which no overall consensus was apparent. I forget the numbers (I was struggling to stay alert), but it was something like 20 to 22. I couldn’t help feeling it’s time to flip a coin, but that’s not how the committee works. On we go…

Swans

Rapperswil in the summer is gorgeous. It’s worth emphasising. The morning light was glorious and I took a moment to sit near the lake before heading back to LWG for some Standard Library Concepts work with Casey Carter, P0898. This involved reviewing a three-way merge between this paper, the C++ Working Draft and the Ranges TS, yielding four colours, cyan, red, gold and magenta to describe different additions and withdrawals from different sources. Take a look. It’s fabulous.

I spent the second session in LEWG as I was very interested in the discussion on constexpr <vector>, P1004. This is a big deal for compile-time programming, particularly strings and reflection, and we forwarded the paper to LWG. This should make C++20. Then my friend and colleague John McFarlane presented his fractional numeric type, a precision-preserving mechanism for carrying out non-integer arithmetic (John, I think it’s actually a rational numeric type myself).

Well, would YOU photograph an animal attacking you?
It’s a duck, not a swan

I was joined at lunchtime by Hana Dusíková who you may know from her astonishing compile-time regex presentation at CppCon 2017. We dangled our feet over the edge of the lakeside, enjoying the tranquil scene, until a swan swam by with her cygnets and bit my toe. Fun factoid: the only people in the UK allowed to eat swans are the Royal family and fellows of St John’s College, Cambridge, on June 25th. I decided against revelling in my non-UK opportunities.

I returned to my presentation after lunch, working on the notes to my remaining slides, and then went back to LWG to look at one of the oldest outstanding papers, P0019 on atomic_ref, which after a second review on Thursday morning was forwarded for adoption into C++20. There were further small things in the final LWG session of the day, and then it was time to party.

Peter Sommerlad had arranged a quite grand event at the castle up the hill from the committee venue. There were alpenhorns, beers, wines and food, in a convivial and stunning environment. I and the rest of the committee were delighted with our host’s choice and our sponsors’ generosity.

An unexpected turn of events

Everyone was a little delicate this morning. I really did drink rather too much at the party.

I dragged myself in at 08:30 ready to continue The Work with LEWG. Titus, the chair, asked for a scribe. Attendance was low. I don’t know what possessed me but I volunteered, in the hope of acquiring hero points. We went through P1026 and P0645.

The first of these is a call for a Data Persistence study group. iostreams is old and the subject of much moaning. This is of particular interest to me: I maintain the memory and IO work in the Total War codebase. Things have changed considerably in the past twenty years as RAM has plummeted in price and kernels have implemented page file backed virtual memory more efficiently. iostreams is no longer “good enough” and there is scope for standardising much more efficient persistence. Do read the paper and join in if this interests you.

The second paper is a long overdue replacement for printf. I first saw this at Jacksonville and am delighted to see the work nearly completed: we decided to prioritise this for the IS, and I hope to see it in C++20. I try to scribe at least once per committee, and scribing is an excellent way to properly acquire understanding of papers, regardless of your mental state at the time.

The next session was devoted to parallelism. I’m still trying to get my head around the detail of this TS, and this was one of those sessions where I was a rather passive observer, but I stayed to try and gain greater understanding.

After lunch I continued tweaking the presentation; storm clouds gathered over the lake in dramatic style. I returned to LWG for P0323, std::expected. We didn’t complete reviewing.

The evening session was billed as a presentation on The Role of Technical Specifications in the evolution of C++, but was a wider presentation of P0939, Direction for ISO C++. I wondered if there would be any air-time given to discussion of the graphics proposal since it is targeting a TS, and the direction paper, in a small aside, does call for the inclusion of a lightweight drawing library by C++20 if possible.

Against my expectations, nearly an hour of the discussion focused on the proposal, with extensive discussion of the motivation for such a thing. There was much debate about the educational value. Personally, I’m not so convinced about the educational motivation although it is certainly the case that new users are always going to be more motivated by visual feedback of their efforts rather than simple character output. Things got quite stormy, and I was relieved that this was happening during this session rather than during my session the next evening.

I was very grateful to the direction group, particularly presenter Michael Wong, for their efforts. However, I needed to comprehensively rewrite my presentation in the light of the discussion.

Act III

I attended one LEWG session today, featuring Herb’s proposal for zero-overhead deterministic exceptions, P0709, and Peter Dimov’s proposal for adding support for type-based metaprogramming to the standard library.

I’m rather excited about zero-overhead exceptions. I prefer this model of error propagation to the rather baroque method of custom propagation via error codes, along with the separation of exceptional code paths. There was strong support for reclassifying out-of-memory errors, along with classification policy for errors, contract violations and so on, as well as discussion about withdrawing std::logic_error whose presence is in itself a logic error, particularly with the introduction of contracts into the language that happened this week.

Walter Brown presented Peter Dimov’s paper. This proposes introducing a library based on Boost.Mp11 into the library. We keep reinventing this particular wheel, and it’s time we put a stop to that.

For the rest of the day I rewrote and rehearsed my presentation. If this were an 80s blockbuster film, now would be the time for the montage.

The evening session on graphics was chaired by Jeffrey Yasskin. He was the chair of LEWG during the development of the proposal. The purpose of the session was to find a way forward, with a new proposal, P1062, being presented followed by my presentation of the current proposal.

At the start of the session there was no overall consensus on whether or not we should proceed with ANY kind of graphics proposal, let alone one or the other, so there was a lot of ground to cover. P1062 offers a refutation of the need for graphics support, and finally proposes a simple asset importing API, while P0267 offers a richer drawing library. Bryce Adelstein Lelbach ran through the content of P1062, and then I presented running samples, showed some code snippets, described the history of the paper and its reception, highlighted the problems of design-by-committee that it had been exposed to and described some ways forward.

Sadly, much of the discussion was about the potential of the speculative proposal rather than the bird in the hand that is P0267. I didn’t make enough noise about simplicity and portability. “Yes” voters left early to return to their rooms in Zurich. Polls of members’ positions were taken regularly, and eventually there was sufficient consensus to stop pursuing 2D graphics in the standard. There was no celebration, just disappointment.

Several thousand hours of work has gone into this proposal, and we need a way of preventing this from happening again. Sentiment transformed from strong long-term support in Toronto to ambivalence in Jacksonville, and this episode sends a rather unpalatable message to those seeking to undertake large proposals. I am confident the committee will find a way of tightening up the proposal and review process to maintain focus and consistency, probably by making demands of proposal writers such as providing a motivation, an abstract, a revision list, a review history and a named champion who will see the proposal through to the end, in addition to providing the actual content.

I deployed the Second Davidson Device in my ruminations paper P0988: my first, least-desired suggestion on how to proceed was to “Nuke it from orbit, it’s the only way to be sure. Buy this author a beer and goto end”. I wasn’t expecting a scorched-earth outcome but the upside was that I bought no further beer during the week. We repaired to a local beer garden and I was loaded up with beer by Bryce and others until I decided I really did have to go home and break the bad news to the rest of the team.

Epilogue

Yeah, whatever.

I spent the day in LEWG licking my wounds. The Work goes on, although to be honest it’s a bit of a blur and I wasn’t really taking much in the way of notes. I was most nudged by a proposal to add stack tracing, monadic operations for std::optional, support for contract based programming, and the fixed capacity vector.

At lunchtime the BSI caucus met to review the week’s proceedings. Everyone expressed disappointment at the outcome of the graphics evening session: there had been unanimous support for the TS and an assumption that there would be availability for programmers soon.

The evening session was devoted to the tooling subgroup, and particularly package management. We have a long way to go yet but I remain excited if apprehensive.

Next morning, the closing plenary saw the adoption of many motions and some interesting wrinkles in the voting process. One vote attracted no consensus and went to the National Bodies (NB) instead, who again did not demonstrate consensus, so the motion was not adopted. The ISO is a federation of national bodies, and although the closing plenary votes are taken from those present who are listed in the global experts directory, NB opinion is the fallback position. I’m a bit of a governance geek, and I found this very interesting: National Bodies are important, representing the opinions and wishes of the community of C++ developers the committee seeks to serve, and we ignore them at our peril.

Committee adjourned, but even though it was over, groups remained to continue further work. There is still a backlog. I returned to LEWG to support P1007, Timur Doumler’s paper on std::assume_aligned which formalises what every compiler does with alignment hints. I caught the train to Zurich airport with Jon Wakely and we watched Switzerland glide past beautifully while we discussed the future of the graphics proposal and its contents.

However

Just because the committee doesn’t want to publish the 2D Graphics TS doesn’t mean the 2D Graphics TS won’t get published…

Oh, lock-free circular buffers, yay! Hey, no 2D graphics? Jacksonville trip report

[ Note: If the jargon is confusing, check out the committee page at the ISO C++ site. Failing that, put requests for clarification in the comments and I’ll amend this post – end note ]

This was not the trip I was expecting.

Plans set in motion

I landed on the evening of Saturday March 10th and checked in to room 1234 (I was making password jokes all week), then spent Sunday combating jet lag, aided somewhat by the start of daylight-saving. I made my plans: I had two papers to present, P0059, concerning circular buffers, and P0267, concerning 2D graphics. The circular buffers paper formed part of the Tuesday evening session on new STL containers, and the 2D graphics paper formed part of the Wednesday afternoon session in LEWG. I decided to spend a day or so in LWG to hear some rhetoric about wording and learn more about the art of good writing for the standard, after which I would spend some time taking the temperature in LEWG before presenting P0267.

Right now, both library groups are processing fewer papers than they receive. There are 19 sessions of about two hours during each meeting, and LWG spent the first five sessions on P0214, Data-Parallel Vector Types & Operations (for the Parallelism TS), which defines some SIMD types. I was delighted to be in on this, and even offered to scribe but found it impossibly hard, unlike my stint in LEWG at Toronto. However, it was during the fourth of these sessions that I started to feel distinctly unwell.

This was Tuesday morning. The evening session was devoted to SG14 containers, which was my opportunity to relaunch my circular buffer paper. I struggled through and was given strong encouragement from the SG1 chair to re-present in Rapperswil in July. SG1 has yet to ship a concurrent container; indeed, there is no such thing in the standard yet. I approached the LEWG chair, Titus, after the evening session and remarked on my poor health; he graciously rescheduled me to Friday afternoon.

What on earth is happening to me?

I spent the next two days in my room, my mind an addled haze of incomplete trains of thought. I felt somewhat improved by Wednesday evening and attempted to join the Unicode evening session: however, Titus sensibly enquired if I was all better and suggested I return to my room if not and avoid infecting others. It was a hard position to argue against. As in Toronto, I attended through Standard C++ Foundation sponsorship and I felt somewhat embarrassed about sitting in my room and failing to contribute. Additionally I needed some stimulus, and I strongly had to resist misquoting Ming the Merciless from the opening of the Dino De Laurentiis remake of Flash Gordon: “Titus, I’m bored: what plaything do you have for me today?” However, sickness is not a kind thing to spread around a community with such a broad age range. One or two of the committee members, while still sharp as nails, are perhaps a little less robust in their years. I returned to my room, my room service and my dissolute meanderings.

Disaster struck when my travel kettle broke. A sick Englishman with no ready access to boiling water for tea is well known to create a mighty psychic depression the size of Buckinghamshire, reaching in to the dreams of those caught in its embrace and tainting them with despair. The room’s coffee facilities could not raise any sensible volume of water above about 85 degrees centigrade, and I was doomed to ingest many cups of insipid yet expensive tea: I bought 40 bags of Harrods Earl Grey No. 42 at Heathrow.

By Friday it was clear I was not going to be able to deliver my ‘A’ game. As the BSI caucus met for lunch in the bar I was still feeling pretty ropey. We got through business and I prepared for my session.

2D or not 2D? That is the question

My aim was to move the paper to LWG to publish a working draft, to prevent further miring and tweaking in LEWG and to give people something solid to write proposals against. I surmised this would free up LEWG time (each presentation of the paper consumes an entire precious session) and draw still more people to the project. An OS X backend was independently developed after my presentation at Meeting C++ just from the paper and the reference implementation, which I took as grounds to indicate that the paper’s development was sufficiently advanced. In addition, there were five years of strong encouragement from LEWG to pursue this course of action. I should of course point out that my co-author Mike McLaughlin completed the lion’s share of this work: I joined the project in late 2016, and it is he who generated this consensus.

However, it’s all down to who is in the room on the day. Everyone in the room gets a vote, and only they get a vote. As the session unfurled it became clear that the room wanted to address the very existence of the paper, rather than its quality or suitability for advance. Ultimately there was no consensus for any action and no advice on how to proceed beyond separating out some of the smaller parts like linear algebra and geometry. The minutes make slightly gruesome reading.

At first sight this treatment might seem unfair. What if it’s your first time at LEWG and you’re not familiar with the history of a proposal? What if you’re ideologically opposed to it even though the paper has been encouraged? You still get a vote? Yes, yes you do. If a proposal is popular and worthwhile then committee members will turn up to help defend it, and improve the numbers during the vote.

Hang on a minute

I left the session early and was joined by Michael Garland from Nvidia to discuss possible future directions and approaches. Perhaps I could offer it to Boost? Maybe we could send command strings to a canvas, browser style? As the session ended and I went in search of tea, I was greeted with commiseration and sympathy from all, detractors and supporters alike.

Suddenly, Roger Orr, who is the head of my National Body the BSI, appeared from nowhere along with Herb Sutter announcing their intent to go to LEWG and seek clarification on what had just been voted for. Herb reminded the group that strong consensus is required to change the status quo but also acknowledged that the process is stuck, and that there should be an evening session in Rapperswil on 2D graphics. Attendance may prove strength of interest and further input may put the process back on the right track.

Meanwhile I’m going to re-examine the component parts of the proposal. Linear algebra and geometry may make good standalone proposals. As a maturing English mathematician (apparently one of the most feared species in this part of the galaxy: just ask Isaac Newton or Stephen Hawking) the linear algebra section appeals most to me.

Wrapping up

The evening session was the inaugural meeting of the newest Study Group, SG15, Tooling. This is a topic close to my heart as a lot of what I do in my job at Creative Assembly revolves around tooling. It was a full session and generated a formidable to-do list. As I indicated in my last post, dependency management and an ISO C++ repository are things I would like to see, but there were so many other reasonable and relevant demands.

Saturday morning shuffled into view. I packed and went to closing plenary, and took a seat at the back, feeling really quite peculiar. As the reports went on I struggled to sit upright, and as Titus started to report on LEWG I started to get quite worried. As he mentioned graphics I fainted. Amusingly, my neighbour thought I was silently passing commentary with comic effect so it took a while for him to realise something was most definitely up. Recovering somewhat, I hurled myself out of the adjacent door and again collapsed to the floor and tried to get into the recovery position. Someone dialled 911. After a few moments things became a little clearer and I could see quite a lot of people around me, particularly three of the officers of the Standard C++ Foundation and the chair of INCITS PL22.16, the US National C++ committee. There was concern and care on their faces, and I realised these are people I actually know. Paramedics appeared, took a spot of blood, measured my blood pressure, asked me questions, advised me to come with them, got me to sign a release form and disappeared with paramedic efficiency. I went back to the closing plenary for voting (my neighbour delightedly proxied for me since by now I was sitting on the floor, disinclined to get up), and business was completed at 12:00 precisely. That’s how we do things.

People wanted to be sure I was still OK, and chaperones were arranged for my return trip to London (nobody came from Brighton except me) – thanks Vittorio! Then some of us went for amazing Dim Sum at Timwah – so good I’m going to link to it here. One of our number drove me to the airport and made sure everything was OK. I left Jacksonville at 17:00.

As we were leaving the ground, I reflected on the committee. At heart, we’re a bunch of decent geeks who want to make the world a better place in the best way we can. We solve problems presented to us daily to achieve this, in small but regular increments. It scales well. The sympathy and respect I observed were part of this, and I know that I will be able to look everyone in the eye cheerfully next time we meet. Also, the committee did everything in its power to ensure my well-being and take good care of me. Health has to come first, not 1449 pages of language specification.

I would, just to be absolutely clear here, like to express my heartfelt gratitude for the response of the committee and its officers during my health incident. Organisations and individuals are defined by their conduct when things don’t go according to plan. Everyone showed themselves to be the right people to put your trust in. Particularly, I want to name Herb Sutter, John Spicer, Michael Wong, Chandler Carruth, Adam Martin and the chap who proxied my vote whose name I didn’t even ask for. Contact me in the comments and I’ll put that right. Thanks everyone. It really did feel like “The gang’s all here” when I started paying attention.

So, now what?

Well, I’m glad you asked.

  • Immediately, I have an AI talk to co-present at ACCU with my colleague Duygu Cakmak. It will be her first time there. Do drop in and cheer her on. And me too if you can spare the energy.
  • I’m going to write something for the post-meeting mailing about 2D graphics, my experience with the process and what I think remains to be done. It will be a ruminations paper rather than a proposal of anything concrete.
  • I’m going to disinter the lock-free revision of P0059, the circular buffer paper, and start iterating with SG1.
  • I’m going to work up a linear algebra paper for 2D graphics. I have a coauthor with additional experience in the field and I have several pages of wording to recycle.
  • I’m going to continue maintaining the 2D graphics library implementation. I’m delighted to announce that the OS X implementation is alive and kicking thanks to the efforts of the new contributor mentioned above, Michael G. Kazakov. We’ll take a view after Rapperswil. Speaking of which…
  • I’m going to attend the Rapperswil meeting. This hasn’t put me off the committee or the process at all. So, yeah, I’ll be back.

Batteries not included: what should go in the C++ standard library?

About forty Christmases ago I was absolutely delighted to open a slot car racing set from my parents. I feverishly set everything up, created a track reminiscent of Brands Hatch, and went to plug everything in, only to discover that I needed batteries to operate the controllers. This was Great Britain in the 1970s. There were no shops open on Christmas Day. There were no appropriate batteries in the house, nor in our neighbour’s house. My delight was transformed to desolation. My parents had an argument. My grandfather distracted me with a story about one of his second world war sorties over the French coast. I watched a James Bond film sulkily. All because there were no batteries in the box.

What prompted this blog post?

With the next C++ Standard meeting in Jacksonville bearing down on us, I have just submitted the next version of the 2D graphics paper, https://wg21.link/P0267. One argument levelled against it runs along the following lines:

“A graphics library shouldn’t be part of the standard library. The standard library is too big already, and this will make it so much bigger. It’s just not appropriate. The library should only contain small types.”

Of course, I disagree with this. I think the library is impoverished and needs fleshing out to make C++ a stronger contender in the development arena.

What is already there?

A quick glance at cppreference.com shows the complete set of headers divided up into the following categories:

  • Utilities
  • Strings
  • Containers
  • Algorithms
  • Iterators
  • Numerics
  • Input/output
  • Localisation
  • Regular expressions
  • Atomic operations
  • Thread support
  • Filesystem

Some of these are more useful than others, and some attract more irritation than others. I know some developers who complain about the input/output, saying it’s bloated and inefficient. I know others who bemoan the incompleteness of the thread support. I don’t know anyone who actually uses the regular expressions, nor the localisation, nor std::multimap.

Then again, who doesn’t use std::vector, std::array, std::iterator, std::find_if and so on? There is plenty to choose from, and some parts find greater application than others.

What could go in the standard library?

One argument is that the standard library should be minimal and complete. It should contain types that require compiler support, like the type traits, and things that are strictly platform specific, such as SIMD support, file IO and atomic operations. The rest is just holding the user’s hand. I’m going to call this level 0 for want of a better description.

If you asked a user to write a mutex, I’m pretty sure they would get it wrong several times before they succeeded. Most likely they would not actually get it completely right and would encounter a peculiar edge case that broke everything at an inopportune moment. It suggests another class of content: things that are hard and error prone. This obviously includes thread support and also memory management. I’ll call this level 1.

Then there are the obvious types that it would be silly to do without. These are the types that are frequently reinvented and are the basic staples of many programs. These are the types such as std::complex, std::array, std::function, std::string, numerics and so on. They aren’t necessarily hard to write, but they are extremely broad in application and it is a safe bet that they will be used by nearly every programmer who will be grateful to have them. This is level 2, and standard commentators will start to murmur a little, remarking on how std::string is an unnecessarily large interface that should be made up of non-member functions, and std::function shouldn’t perform allocations.

What’s left on the list? The STL is one of the wonders of the modern age as far as I’m concerned but it doesn’t fit into any of the prior categories. The containers, iterators and algorithms aren’t “obvious” types, and there’s no particular need to have them in the library, but they’re incredibly useful. This is level 3, and here is where standard commentators start to get quite restless. They might remark that these types and functions are really quite large and bulky, they soak up implementer time, and they should have remained in a separate library.

What do other languages have?

Hand on heart, I’ve been full time C++ for twenty years now, with very little exposure to other languages, so I can’t speak from much experience. However, when you look at Java and C#, you find absolutely huge library support “out of the box”.

The Java Class Library consists of, at first glance, support for UI, database connection, networking, sound, image manipulation, XML, CORBA, encryption, even hosting for scripting languages: the list goes on.

If you decide to open Visual Studio and start writing a program using C# you have the Base Class Library (BCL) at your disposal along with the .NET Frameworks (FX) which together include support for networking, reflection, threading, XML, and parallelism amongst others. There is tooling for building GUIs too, and of course there is LINQ.

These languages are made a little differently from C++ though. Java is owned by Oracle, C# is owned by Microsoft, but C++ is owned by no corporate entity. The development of C++ is controlled by a public process which makes it rather slower to grow. Meetings to discuss, and vote on, what should be added and amended must be inclusive and public. However, there is an enormous wealth of support from these languages that would fit in at level 3, and it seems obvious to me that this support contributes to the popularity of those languages.

Having said this, it’s important to note that bigger is not necessarily better. I don’t think it is controversial to remark that these frameworks err on the large side. However, there is a useful core which I contend is larger than the standard library. That useful core drives the success of these languages. There is clearly a “critical mass” that can be achieved, and while those languages have erred on the other side of that mass, C++ has yet to reach it. I would rather we overshot a little and reaped the benefit of greatly increased adoption.

What typical jobs can’t be done “out of the box”?

Consider my opening anecdote of a Christmas in 1970s Great Britain. A more adult version of this is experienced by many learners who try and solve programming tasks using C++. Would you like to open a socket? Nope, can’t do that. Decompress a stream of data? Sorry, no. Open a dialog box? No. How about telling me what pixel my mouse is pointing at? Ummm… no. Flash some LEDs? Play a sound? Turn off the power? No, no and no.

It’s still the 1970s in C++ land.

What do we do instead?

Your toolchain will come with bindings for interfacing with the host operating system, which should solve network, power, sound and UI issues.

There is also a huge ecosystem of libraries. It really is impressive looking at the amount of code out there for people to choose from to solve your problems. Boost contains an Aladdin’s cave of riches. GitHub is overflowing with niche solutions for all manner of problems.

However, this tyranny of choice is paralysing for newcomers to the language. Operating system bindings differ for each OS. A fresh user cannot sit down with one book and any toolchain and learn the language through solving some real world problems: there is other, platform specific stuff to know.

Not only that, but not all code shops will permit the use of third party code beyond a language and its library. There are commercial, industrial and military environments that insist all code is created in a “clean room” environment. The arrival of software patents has made this an even more complicated matter.

Is there another vehicle for larger types?

As I said, I have skin in this game. I think a standard 2D API will be a great benefit to the library and I have one that’s nearly ready to go. I am keen to turn it into a Technical Specification and then see it incorporated into the International Standard.

But is there a destination other than the IS where it might be published?

At the moment, no, there isn’t, but I can envisage a repository of source libraries that have been “blessed” by the committee which exist outside of the standard. At the moment the committee consists of two streams, the library and the language. A third stream could be introduced which reviews candidate libraries for inclusion in this repository, rather than being added as level 3 contributions to the International Standard.

This repository could come with clear rules:

  • All conforming implementations would have to be able to build it entirely.
  • Contributions should not be burdened by licensing restrictions.
  • Updates to the source should be reviewed by the committee.

What I’m talking about is a package index, or better still, a package manager. The former will retrieve libraries, while the latter will manage dependencies and auto-updates. If you’re writing some code in a blog post that uses graphics, you should be able to instruct your readers with something like

To build this code, type "cpp-get lib-graphics 1.56" at the command line.

and it should Just Work. It means we can assume every developer has access to a particular library.

There are already several developers looking at ways to implement a package manager. There are some mature efforts out there. Conan, apt-get  and vcpkg are a godsend: indeed, the 2D graphics paper’s reference implementation relies on vcpkg to install the support libraries. But, and it’s a big but, we don’t have a standardised package manager or index, like Python’s PyPI (over 120,000 packages!), ready to power any C++ implementation with the extra voltage needed to write truly useful programs out of the box.

In summary, perhaps there are two ways to ship libraries that can be assumed to be accessible to all C++ developers:

  • In the box (i.e. in the International Standard)
  • In a package index (To Be Designed)

I hope that at some point in the near future something will emerge blinking into the light of day and we can examine an additional way of growing the standard library.

Acknowledgements

This post started as a pair of email conversations. One was with Titus Winters, chair of the Library Evolution Working Group. Several portions are lifted with gratitude directly from his words. The other was with Herb Sutter, chairman of the ISO C++ Working Group, and Richard Smith, C++ project editor, to whom the same thanks are directed. Many thanks also to Herb for review commentary and corrections on the organisation of C#. Remaining errors are of course my own.

Trip Report: My first ISO C++ Standards meeting

On July 8th 2017 I landed at YYZ in Toronto, ready for a week with over a hundred C++ experts thrashing out the details of improvements to the standard. This was my first standards meeting and I didn’t really know what to expect: I’ve read many trip reports but they tend to speak of the results more than the process. This post will describe more of the process.

Day 1

After an uncomfortably large breakfast I walked to the meeting venue. The meeting opened with a plenary session. This session described what the order of business would be and described administrative points. The day started at 09:00 but this was exceptional: the remaining days would start at 08:30.

As you might expect, the room was full of people whose names you know but whose faces you haven’t necessarily seen: there was an introductions point during this session where everyone announced their name and role in turn. Additionally, diversity was rather limited: although the age distribution was good (retirees still turn up to offer the benefit of their experience, and there were undergraduates present) it was rather white and male.

Business is done by each group in their own room. There are eighteen groups in total: four working groups and fourteen study groups. The working groups work on the language (these groups are named Core and Evolution) and the library (named Library and Library Evolution). Papers arrive at the evolution groups where they are considered for inclusion in the standard, and then forwarded on to their partner for final checking before inclusion into the standard. Some papers will have an impact on both the language AND the library. Concepts, for example, requires new keywords to be added to the language, and for many library features to be decorated with their concept requirements.

The working groups were active throughout the entire meeting. There were four sessions scheduled each day of between 90 minutes and two hours. Papers were presented, discussed, and accepted or returned to the author for further development.

For the first day I decided to spend my time in the Library Evolution Working Group (LEWG). There were about a dozen of us looking at the ranges, networking and coroutines TSes before forwarding them to the Library Working Group (LWG). We also considered a paper on endian-ness from Howard Hinnant (P0463) and a paper on the “spaceship” operator from Herb Sutter for consistent comparison (P0515). These paper numbers can be appended to https://wg21.link/ to retrieve the latest revision. I’m not going to provide links to the papers: you can make your own links now!

In the evening Titus Winters presented P0684 about how we go about delivering new versions of C++, and we finished at about 21:30. I was remarkably tired, which may have been down to jet lag or the huge amount of challenging thinking I did all day.

Day 2

I planned to spend time in each of the working groups, but I made my way to LEWG again as I had an interest in one of the papers scheduled for the first session. However, Walter Brown entered the room remarking that LWG was seeking a quorum and I decided to help out. Walter is the model of professional courtesy and it was hard to turn down such a politely made request.

The task at hand was checking issues with the Ranges TS. Eric Niebler and Casey Carter were iterating through the GitHub issues which were largely wording related and the rest of LWG was requesting clarification or amendment. There were half a dozen of us; the group is rather less attended than LEWG and the work is a little more particular.

The role of LEWG is to see whether a paper should be considered for inclusion in the standard or not, while the role of LWG is to ensure it’s correctly worded before passing it for publication. LEWG is a more exciting place to be as this is where the new stuff is unveiled, but LWG is necessary and needs staffing. It was very interesting seeing the process unfold, as clauses were decided, phrased and ordered appropriately. The standard is a legal document, and must be unambiguous: a lot of blue-pencil work is required. This satisfied my OCD demon.

Committee time is very valuable and there is little time for digression. We got through nearly all the outstanding priority one and priority two issues: the end was in sight but we had to follow the schedule and stop. Eric asked for volunteers to complete the job at lunchtime the next day and I offered my time. There would be pizza, plus the chance to complete the Ranges TS.

I have two papers in flight at the moment: Adding circular buffers (P0059) and Adding a 2D Graphics API (P0267). The graphics paper was scheduled for the afternoon but the nature of the paper is such that it requires a lot of eyes going through parts of it. Things were hotting up in the Evolution Working Group (EWG) as the Concepts discussion was nearing an end, and numbers were depleted in LEWG, so the graphics paper was postponed to the next day. Instead, more digestible papers were considered.

Howard Hinnant presented his paper on calendars and time zones (P0355). This is a completion of the work started with <chrono> for working with hours, minutes and seconds, introducing classes for time zones, days, months, years and calendars. This is a substantial undertaking to say the least, complicated by bringing in a dependency on an external time zone database maintained by IANA. I still feel a little queasy about this but it’s clearly the only solution unless WG21 decides to adopt time zone management into its charter. That isn’t going to happen, of course.

The evening was taken up by an extra session for the Evolution Working Group (EWG) on Concepts syntax (P0696). There was heated debate about complexity and even discourteous conduct which the chair, Ville Voutilainen, had to bring to order. In all honesty, I was uncertain why positions were held with such passion, but there was resolution and eventually consensus. At the back of my mind was the desire for everyone to kick off C++20 with some TS inclusions.

Day 3

The graphics paper (P0267) was examined. It’s a big beast, weighing in at nearly 150 pages, and had garnered quite a bit of interest. Numbers were strong and the room was divided into three groups to look at two sections each. This was a common trend in LEWG: some papers do not need to be analysed by the entire room, so the group will parallelise the task and consider several papers simultaneously, returning to the entire group to present findings later in the session or at a subsequent session.

The paper is mature: although I am the co-author I only joined the effort a few months ago. Michael McLaughlin has completed the lion’s share of the work. We are seeking adoption of the paper into a TS, or Technical Specification, to get feedback from the wider C++ community. Just as Modules, Concepts, Networking and others have been offered for gathering early opinion from the final users, so we want to offer Graphics. This was not that day though, and further effort needs to be undertaken.

If graphics interests you, you can find the paper and a reference Windows implementation on GitHub. I’ve already (partially) written an Asteroids game using the implementation, and I look forward to the efforts of others. I’m sure there are more games ready to debut within the API. I might try organising a competition with prizes if interest is high enough. Watch this space.

Lunchtime rolled around and I raced to LWG. We had overrun a little in LEWG and I didn’t want to miss the pizza. Fortunately, the ordering had been generous and I settled down to minutiae over pepperoni. Ninety minutes were allocated to lunch each day, and in that time we finished all the Ranges TS issues and heaved a sigh of relief. Come the Saturday plenary, the Ranges TS could be advanced for publication. The remaining task is editorial: all the changes that have been proposed and voted for now have to be verified as present in the TS. This means that someone, or rather several people, need to go through each one line by line and check it’s there. This is called the editorial committee. I volunteered: it’s an excellent way to learn the feature, and I haven’t actually digested the whole TS yet. What better opportunity so to do while also being useful.

During the afternoon session I returned to LEWG to see my other paper being reviewed. It’s good to go, and I’ll be coming up with wording for re-presentation at the next standards meeting. We looked at two other containers also, the flat_map (P0429) and the slot_map (P0661). These associative containers will speed up dictionary lookups enormously. LWG issues a Library Fundamentals TS (version three should be started any time now) and these containers would appear in there once they have passed through LEWG and LWG.

I started noticing people yawning. The standards meeting is not a relaxing holiday: it is hard work to constantly analyse papers critically and consider their impact on the rest of the standard. A whole day’s work is tiring and it’s worth recalling that this is a voluntary effort. Nobody is paid to do this.

In the evening however it was time to relax a little. Waterfront International sponsored a celebration of C++17 and we went up the CN tower to eat and drink at their pleasure. The event started early in the evening while it was still light, and as night drew in the glittering tablecloth of man’s endeavour became apparent on the land all around us, as the street and office lights appeared. Most of the software that enabled this was probably written in C++.

Day 4

I remained in LEWG; Daniel Garcia presented his contracts paper (P0542) which looks like assert on steroids. We were delighted to pass this forward to LWG. Alisdair Meredith had a paper deprecating lots of stuff from the standard (P0619). I take great joy in removing lines of code from the Total War codebase. I took similar joy in evicting no-longer relevant items from the standard.

We also looked at an example distribution of the standard library headers when modules appear: which modules will receive which headers? There was a string formatting paper (P0645) which greatly improves upon printf.

I normally spent my lunch break with a couple of colleagues in the local Belgian pub, The Prenup, which served good food and beer. It felt somewhat British, although the poutine was distinctly local.

In the afternoon we looked at P0244 which was about character encoding, and reviewed the slot_map further. I did some scribing. All the sessions require a note taker whose job is to record discussion, reasoning and proposed action points and the results of straw polls. These straw polls take the form of a question and a choice of five options from Strongly For to Strongly Against. This is how all the decisions are made. Scribing is hard but important. Unfortunately ISO rules forbid recording, so the whole things has to be done by typing as people speak, which is not an easy task, as I discovered.

Notes are kept in the wiki, which is hosted by Edison Design Group. The wiki is the sum total of all considerations of the committee, organised by venue, and then by working group and study group. Each group gets a page and the chairs are able to use their page to post relevant information during the meeting, for example a schedule of papers to be investigated, the day they are likely to be investigated and any polls and outcomes. Each paper gets its own page for notes, discussion and polls. These notes can be used by absent authors to guide future development of their papers.

SG7 met in the evening to cover reflection papers. The Study Groups specialise in particular domains such as concurrency, modules, networking and concepts to name just four. Domain specialists populate these groups, generate papers and forward them to the appropriate working group. Papers will typically go to the evolution groups.

The study groups met for one or two sessions throughout the week, although SG1, the concurrency group, met for every session. There is a lot of work to be done. There were additional evening sessions for extra work. There was always something to help with in the evening. SG7 discussed static reflection of functions (P0670) and metaprogramming by design, not by accident (P0425). There was also a presentation from Herb Sutter on metaclasses (P0707). If you were at ACCU earlier this year you would have seen his keynote and you will recall the palpable excitement; I will remark that it was as well received in Toronto as it was in Bristol.

Day 5

Having spent time in LEWG, LWG and EWG, it was time for me to visit Core (CWG). We were working through the Modules TS (D0702), ensuring wording was correct. After the discussion in the other groups, the silence was deafening, broken only by the thrum of the air conditioning. I actually whispered to my neighbour.

The Modules TS is 16 pages long, and there’s plenty of whitespace, but it still took several sessions to clear. There were 18 people in the room carefully examining all the text for impact on the standard and for inconsistent phrasing that could introduce ambiguity. The pdf was modified on the fly by the author, Gabriel Dos Reis, sitting in the corner of the room composing while we verified, and we hit reload on our laptops as each correction was submitted. Additionally, the wiki was heavily edited and refreshed by Jens Maurer as business was conducted. You could see our workings in real time just by refreshing the wiki periodically.

I made my first direct contribution to the standard by correcting the use of an indefinite article from “an” to “a”. My delight was observed by Richard Smith, the WG21 project editor, for which he offered a fist bump. It was a glorious moment. There is NO petty pedantry in CWG. It’s all important. Clarity must be maximised, ambiguity must be minimised.

We completed the Modules TS and moved on to the Concepts TS in the second session. I suddenly noticed just how much cable there was in the room. Everyone brings a laptop so that they can keep up with the wiki and that means power cables and plug adaptors for the international members. We are still a long way from the wireless, paperless office.

The final session of the standards meeting is another plenary where many motions are voted on, mostly along the lines of “Incorporate this paper into the standard”. Voting members include representatives from companies and national bodies, such as the British Standards Institution (BSI), as well as individual members. The rules about who can vote are complicated. Check with your national body or contact the convenor of WG21.

The BSI caucus met for lunch in The Prenup to consider some of the more controversial papers to see what our position would be.

I returned to CWG after lunch for more drive-by fixes to the Concepts TS, but I was summoned via IRC to LEWG to discuss the container papers, including Matthew Reece’s Colony proposal (P0447) which I was presenting on his behalf. As the day drew to a close we finished up as many LEWG proposals as we could, and added another function to std::string (P0457). We couldn’t attend to all the papers that were offered for scrutiny, so there are some which will be either postponed to the next meeting or will be analysed by LEWG experts in the interim.

There was no evening session. We repaired to my hotel bar. In general the host will try and arrange a single venue for meeting space and accommodation, but this time there were two hotels and a separate meeting venue, the Bahen Centre at the University of Toronto.

Day 6

The closing plenary session had a light-hearted, celebratory mood. The study groups reported on their activities this week, as did the working groups, and then we moved on to the motions. We moved coroutines, ranges, and networking TSes to editorial committee and publication, we advanced modules to ballot where it will be reflected on by the national bodies, and made modifications to the C++ working paper by including such papers as Howard’s Endian proposal.

We passed 36 motions altogether. The plenary isn’t a rubber stamp: some motions had objections and votes were taken. During the plenary I was notified by email from the BSI that I was able to vote: the process was complete. Fortunately, no motions were hanging by a thread, but it was good to raise my hand to register my support for the TSes.

With that, we were finished. We dawdled outside, chatting and promising to stay in touch, then retreated to the Prenup Pub for further beer and food, slowly drifting away as our schedules demanded. Weirdly, my plane seat was directly behind the BSI delegation chair and his wife, who had come for a holiday while he sweated over CWG.

I had the time of my life and I would choose this over a conference any time. Many thanks to my employers, Creative Assembly, for giving me the time to attend, and to the Standard C++ Foundation for funding my travel and accommodation.

Post script

Should you decide to attend a meeting for the first time, here is a to-remember list:

  • There is a wiki. Make sure you retrieve the URL and login details from another delegate.
  • All the groups are different in attendance, character and operation. Try them out.
  • wg21.link is your most useful tool.
  • Volunteer for things. History is made by those who turn up.
  • Everyone is a volunteer. Nobody is out to impress anybody.
  • If you don’t know something, take this rare opportunity to learn from the designers.
  • Sleep well, eat properly and stay hydrated. It’s easy to forget when you’re concentrating on other things.
  • Don’t be embarrassed about leaving sessions early: maybe you can’t contribute, or it’s over your head, or you don’t feel you can learn. Find somewhere else to learn or be useful. Or stay. Your choice.

Here are the things I volunteered for:

  • Reaching quorum at LWG
  • Writing a paper about unifying how the standard refers to Undefined Behaviour
  • Ranges TS editorial committee
  • Scribing
  • Reminding Jeffrey Yasskin, LEWG chair, that we need a graphics teleconference

I’ll be blogging about the graphics paper in the coming months. Stay tuned.