I love Czechia and I love Prague. I have visited a few times: most recently to give a talk at the Avast meetup last February, organised by Hana Dusíková, who also organised this WG21 meeting. She did an absolutely outstanding job, and I know that I share that opinion with many committee folk.
Of course, this was the meeting that C++20 was due to be signed off by WG21 and sent for polling by the National Bodies (NB) before going to ISO for publication. Plenty of time was spent on attending to outstanding NB comments but there was still scope for reviewing new proposals.
On top of that, there was a social event on Wednesday evening to celebrate the release, which took place at Pražská Křižovatka. The whole week was as tiring as ever, but I was delighted to be there, to make “the team photo” and to advance some of my work. If you are interested in a detailed report of the work completed you can find one on reddit: I am going to discuss my work and experiences.
I arrived on Sunday morning, having foolishly decided to catch the 08:20 flight from Gatwick which required me to get up at 05:45. Prague really is gorgeous at any time, but I was fortunate enough to be awarded an upgrade and to get a room on the top floor, commanding astonishing views of this beautiful city.
Of course, veterans of this column and of the meeting process will know that looking at the city was about the only thing for which I would have the opportunity. However, after spending an afternoon in preparation, I was able to join several colleagues at a nearby bar: from Creative Assembly, Duygu Cakmak and Nick de Brueck, and also James Berrow who has been working on a colour proposal with me for the graphics effort.
Hospitality really is very, very generous in Prague: after four beers and a pizza I was ready to call it a night, having spent a wallet-whispering £12. This was to be the pattern throughout the week: several of us would go out and eat a fine lunch for the price of two coffees back home.
P1385 is up to revision 6 now, since the post-Prague mailing. It is the fourth meeting at which it has been reviewed, and the third meeting at which LEWG-I has been a reviewer. We spent two full sessions, equivalent to half a day, interrogating design issues. The outstanding issue was, again, the issue of operator overloading: should you be able to write A*B to multiply two matrices, two vectors, or a matrix and a vector, and what should it mean? This turns out to be a surprisingly subtle question.
I know that some people are getting a little impatient, but we do have to get this right. The proposal is a little under 50 pages now, and we haven’t even added any wording. These things take time! Bryce, the LEWG-I chair, estimated another one or two meetings before it would be ready to move on to LEWG. With a couple of meetings there, and another couple of meetings for wording correction, we should make it into C++23. There are nine meetings in total per cycle.
I was interested to discover that there are already dependent proposals waiting for our proposal to make it into the C++23 working draft, particularly Physical Units by Mateusz Pusz and the upcoming colour proposal. Speaking of which…
There was no new revision for the graphics proposal this time, but an interesting paper did appear which critiques the work so far. It is an excellent paper and paid a lot of attention to the ways in which colour can be incorrectly manipulated. I contacted the author and asked him to coauthor a colour proposal with me, and encouraged him to join the UK National Body and attend the Prague meeting to present his findings.
Colour is hard and confusing. James prepared an excellent presentation to SG13 that took well over an hour to deliver. He covered the salient points but even then it was just an introductory session. He carefully fielded every question and it was an incredible and revelatory time for all. James is to be applauded, especially considering it was his first engagement with the standardisation process.
The main source of confusion is the difference between linear and non-linear colourspaces. We are all used to RGB colour values on a monitor, but if you want to blend between two colours you need to use a linear colourspace, which RGB is not. This causes problems for any kind of interpolation: you must convert to and from a linear colourspace. Since a colour is typically a vector of three elements, this conversion is achieved through matrix multiplication, hence the need for linear algebra.
Surprisingly, this category of error is observed throughout most graphics libraries, which lends additional weight to the need for a colour library. Watch this space: James and I hope to bring a paper to the next meeting.
If you have read Timur Doumler’s trip report, you will know that we are floundering somewhat. Although we (very nearly) have a proposal and implementation, the committee isn’t quite sure what it wants. Timur co-authored a paper with Sophia Poirier and Frank Birbacher which listed some use cases for audio. It is to be hoped that this will focus the minds of the stakeholders and we can make some progress.
The real problem, of course, is that myself, Timur and Guy Somberg all have day jobs, and the world is suddenly a rather peculiar place. As I have mentioned before, the entire effort of standardisation is voluntary and if there is nobody to push the work forward, it doesn’t happen.
I have a vision for SG13, which is to enable C++ engineers to use standard language and library features to portably develop rich media applications. It is a long march, and I am fully aware of this. Piece by piece it is falling into place though.
Hana scheduled a formal dinner to celebrate the completion of C++20, and asked everyone to dress up and wear something sparkly. Sparkly isn’t really my style, when it comes to dinner. However, I recently joined the Brighton Festival Chorus, a requirement for which is the possession of a dinner suit for performances. I added a top hat and decided that would be my outfit. I decided I ratherresembled a 19th centuryEuropean gentleman.
It turns out we did not disappoint, nor was mine the only top hat. There was a variety of very well turned out guests, along with the inevitable scattering of refuseniks in shorts, and an excellent time was had by all. A grand piano sat on the stage awaiting the attentions of several of the committee, and we seem to have a large number of members who know there way around another type of keyboard.
This is the end of my first C++ cycle: my first committee meeting was Toronto 2017, which was the first meeting of C++20. The next committee meeting was scheduled to be in Varna, Bulgaria, but times are strange now and that won’t be happening; I hope it has been postponed a year, as I would love to visit the Black Sea. Also, Creative Assembly has a sister studio in Sofia, so a visit would be excellent. The committee is looking at virtual meetings and teleconferences, so do contact your national body if you are interested in participating: the barrier to entry has never been lower.
Many thanks, again, to the C++ Foundation for sponsoring my attendance.
November turned into a heavy travel month when I agreed to speak at both C++ Russia in St Petersburg and Meeting C++ in Berlin, either side of the Autumn WG21 committee in Belfast. I took what some considered to be “quite a risk” with St Petersburg: the date straddled the Brexit date, and I would be accompanied by my wife whom the organisers graciously agreed to pay to accompany me. She travels with an Irish passport, so the idea of both of us safely returning to the country immediately after a change to border law seemed potentially hazardous.
Of course, Brexit was again postponed, but this concern also sat with many of the WG21 delegates when considering their travel plans: many flew to Dublin and took a coach to Belfast. Nonetheless, opening plenary on Monday morning was full as we started going through the motions. Since we were in the UK, my national body, the BSI C++ panel, was well-represented by upwards of 20 delegates, many of whom were attending for the first time.
My first meeting was in Toronto, where we started work on C++20, and this was my first meeting at the other end of the process, resolving national body comments. The four working groups were focused on resolving issues raised by individual national bodies, which are composed of C++ experts who don’t all necessarily attend the committees. There are two meetings dedicated to fixing these at the end of each cycle; Belfast was the first.
While the working groups were processing the comments, the study groups continued with C++23 issues. Although I had chosen to spend most of my time in LEWG and the rest of the time defending my papers, I found myself pulled towards SG18, the incubator group for LEWG, known as LEWG-I and spent most of the week there maintaining quorum, considering new proposals and occasionally scribing.
I started in LEWG, where new policy was formed relating to how things are done. This is a feature of LEWG life. Of particular interest to me was expanding the rights described in SD-8, a standing document which warns users of the language what the committee reserves the right to do. So, for example, you are entirely at liberty to add identifiers to the std namespace, but the committee reserves the right to define symbols which are spelled the same as your identifier but which have completely different meanings. The moral remains “stay out of the std namespace”.
After lunch the first linear algebra review took place. There are two papers: P1385, the syntax paper I am co-authoring with Bob Steagall, which reserves some identifiers and describes operation for linear algebra, and P1673, the BLAS paper which seeks to wrap BLAS in a C++ interface. All review is good review, and although the papers were forwarded by SG6 to LEWG at the last meeting in Cologne it was good for everyone to keep track of progress.
The committee took place in a hotel where many of us were staying, so we gathered in the bar after business to catch up with each other. The committee resembles the tennis grand tour, with many familiar faces travelling the globe from city to city.
I spent the entire day in LEWG-I. The schedule was to get through the linear algebra papers in the morning, and then move on to low-level file IO in the afternoon. Both of these topics interest me greatly: besides linear algebra, one of my projects at Creative Assembly on Total War is our virtual file system which copies data from offline storage into the process.
We were rather defeated though: we only made it through the BLAS paper but as a result it was forwarded to LEWG. We were short on time so we moved on to std::breakpoint, which as you might guess is a proposal to allow inserting breakpoints into code such that the running programs is suspended and a debugger may be invoked. We considered other names: I suggested std::pause which was roundly dismissed. break is already a keyword, so that’s not feasible. Naming is hard.
After lunch we took a look at P1883. Niall Douglas is attempting to improve standard file IO: at the moment we have fstream which fails on the issue of separation of concerns. It bundles together file IO, the filesystem and formatting into a single entity, rather than making the concerns composable. This was an exhausting pair of sessions. Niall is an excellent presenter and took us through a walkthrough of his file_handle proposal. There was SO MUCH TO LEARN though; I only work on Windows and my knowledge of POSIX is sketchy at best. Any proposal has to accommodate all the targets and be implementable everywhere, a costly lesson I’m learning while trying to work out how to implement host input for 2D graphics.
My colleague Duygu Cakmak was attending for the first time. She truly grasped the effort required to build the standard. We stepped out for supper before the evening session and commiserated about how tiring this was. The day wasn’t over though: the evening session was about exception performance measurement, a consistent pain point over the past few years to the committee. Ben Craig had interesting data to present about the cost of being exception safe.
I did some scribing on Wednesday morning in LEWG-I. Everyone should try it: the chair was tipping scribes with Nvidia rulers, one of which now has permanent residence in my satchel. It’s easier than it seems, and it’s an excellent way of focusing your attention on a particular paper.
In the afternoon we continued with file_handle and completed the paper: three sessions well spent. Do take a look at P1883 and consider what is coming down the tracks towards us. Bob and I were also offered review in LEWG-I of P1385 and got excellent additional feedback which we can improve the paper with. I’m looking forward to advancing the paper further in Prague in February.
There is a problem on the horizon: the size of the C++23 backlog in LEWG. I heard numbers being bandied around suggesting there were 80 papers already in the queue. I don’t know the precise number but getting a paper out of LEWG-I and into LEWG does not mean we can expect linear algebra to be ready for the end of next year. However, our plan is to continue improving our implementation and make it available to Compiler Explorer. We also recruited a BSI delegate, Antony Peacock, to write a small matrix customisation using the SIMD proposal; he was introduced to a relevant Intel delegate who happened to be in the room at the time. The committee is the best place for C++ networking bar none!
A few of the BSI delegation went out to dinner: there were over 20 of us at this committee, the biggest so far. I had a blue steak which I came to regret…
History does in fact repeat itself, and as in Jacksonville 2018 I fell ill, although this time seemingly with food poisoning. This was rather unfortunate, since this was the day set aside for 2D graphics and audio. More precisely, SG13 met in the morning but I was only able to make the second session where we reviewed the audio proposal. This is going well: we hope to put this into Boost during the standardisation process.
My co-author on the 2D graphics proposal kept me up to speed though: this revision (R10) contains more detailed feedback from critique papers and some corrections. We have a text API now and have “only” to sort out cross-platform input, as described above. I hope to have this done for Prague, although Varna in June seems more likely since it is a mere nine weeks to the Prague mailing deadline.
I returned to a LEWG-I/SG6 joint session to hear Chris Di Bella defend a paper about a concept design for the numeric algorithms. SG6 were meeting in two rooms simultaneously, a first I’m sure, but entirely appropriate for the group: reality is ours to describe, after all. This is a great paper attempting to describe concepts like magma, semigroup, monoid and so on. It led to my favourite poll of the week, where we had to decide on a name for the zero_element, which when applied to another element in a field produces itself (think of multiplication by zero). zero_element was deemed unfit because it’s not an element of a container, annihilating_element was similarly unpopular, so we ended up deciding on annihilator. I am delighted with this name, although the chair was less impressed; he should be pleased we didn’t choose ‘destructor’.
And with that, the group work was completed. I retired to my room but was persuaded from my bed (yes, I was actually in bed) by the BSI delegation out drinking in the city. We sang songs accompanied by an acoustic trio in a pub. Many of the BSI delegates were attending their first meeting, yet we spoke about our plans for Prague.
Closing plenary voted nearly all of the work through to the standard. 75% of the national body comments were addressed, which puts us in excellent shape for sending the draft for publication at Prague.
We parted in high spirits. I have a full plate for the next few weeks but I’m looking forward to Prague very much indeed. Many thanks, as always, to the C++ Foundation for sponsoring my attendance.
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.
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
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.
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.
The command line – the most obvious way
Importing dependents – declaring in the project properties that a project is dependent on another
#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:
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.
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.
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.
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…
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 finalised: the 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.
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
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.
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.
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!
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.
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.
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.
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.
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.
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!
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.
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.
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.
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:
Write some samples or tutorials
Propose text or input APIs
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.
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.
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 +.
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…
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).
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.
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.
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.
Just because the committee doesn’t want to publish the 2D Graphics TS doesn’t mean the 2D Graphics TS won’t get published…
[ 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.
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.
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.comshows the complete set of headers divided up into the following categories:
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.
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.