WG21 has a strict schedule (see
P1000 ) for issuing a standard every three years. And no delays.
During each cycle, we regularly receive questions “why so strictly?”, Especially from new committee members who are not familiar with its history and the reasons for the current state of affairs. And during the preliminary conference call with the administration of Cologne, several people recommended describing why we are doing this and how the decision was made to accept this schedule.
I wrote all this in the form of questions and answers for the next draft of P1000, and sent a copy to the committee members who were heading to Cologne. This material will be published in the next public version of the P1000, we will distribute it in a few weeks from now.
')
However, the draft FAQ may be of interest to the public, therefore I offer you a copy of it. I hope it will be for the most part useful for you, in some ways it will enlighten, and maybe even entertain you a little.
There are bugs in the standard, should you postpone C ++ 20?
Of course, yes and no.
We are moving in a given direction at the selected speed: bug fixes are scheduled for this last year, so the schedule in early C ++ "19" (Kona) sets a deadline for feature freeze in C ++ "20" to we had a year to fix bugs, including working with comments from different countries this summer. Before the beginning of 2020 (meetings in Cologne, Belfast and Prague) we must give feedback and apply any other solutions to the problems, as well as fix bugs.
If you hold another one or two meetings, you could add a <name_of_bychi> that is almost ready, so should you delay C ++ 20?
Of course, yes and no.
Wait for another couple of meetings to take place (after Prague), and C ++ 23 will be open for business, and first of all we will vote to add <name of the name> to the working draft of C ++ 23. So we did with the concepts: they were not ready to move from TS directly to C ++ 17. Therefore, at the first meeting in C ++ 20 (in Toronto), they voted to transfer the main functionality of the concepts to the draft C ++ 20, which gave a lot of time to improve and refine the rest of the controversial part of the TS (non-"template" syntax) next year (San Diego). Now all the functionality is ready.
It seems too strict. Why release IS releases at fixed intervals (three years)?
Because in the case of the C ++ IS release, this is one of the two main options for project management, and experience shows that this option is better than the second.
What are two project management options for C ++ IS release?
Glad you asked.
In the case of a release, there are two main options: select features or release dates, and when you choose one, you lose control over the definition of the other. It is impossible to simultaneously control both. In short:
I explain:
(1) “What”: we choose features and ship as soon as they are ready, no need to choose the release time . If it turns out that you need more time to finalize the features of the draft standard, then the whole world will have to wait for you. You work on big features that require several years of development, and then you try to stop working on new features altogether while you stabilize the release.
This was the case with C ++ 98 (it was waited around 1994, Bjorn said that the release will not work by that time, it will be a failure) from C ++ 11 (it was called 0x, because x was waiting for 2007) . This is the “leave the patient unprotected” approach for an indefinite period, which has led to a delay in integration testing and release. And this, in turn, led to great uncertainty in the market regarding the timing of the next standard, and whether it will come out at all (yes, not only the participants of the development, but even some members of the committee seriously doubted in 1996 and 2009, whether any relevant releases). For several years, most compilers did not meet the standard, because no one knew how many incompatible changes would the committee roll out in a new release, or when to wait for it at all? This has led to a lot of diversity and fragmentation of C ++ support in compilers available to the community.
Why did we do that, are we idiots? Not really, just inexperienced and ... let's say, "optimistic." It was a road paved with the best of intentions. In 1994-1996 and in 2007-2009 we really believed that now we would move on to another one or two or three meetings, and we would do everything, and each time we transferred them for periods of up to four years. And now, in my own experience, we were convinced that there can be no transfer for a year or two.
Fortunately, everything changed due to option (2).
(2) "When": choose the release date and ship those features that will be ready, no need to choose a set of features . If it turns out that you need more time to refine the features of the draft standard, we throw it away and ship what is ready. You can continue to work on large features, the creation of which takes time like a few releases, but do it in third-party "branches", adding them to the IS master branch as soon as it is ready. And you constantly work on features, because their development is completely separate from the current release (there is no big connection point).
We have been following this approach since 2012 and we don’t want to give it up. This is the “regularly sew up patient” approach, which leads to the expectation of higher quality due to compulsory regular integrations and the refusal to add work to the IS draft until it reaches a certain level of stability, usually within the framework of the feature branch. It also creates a predictable release cycle on which the market can rely. Over the years, compiler authors have begun to release, after the next release, the standard versions of their products, which has never happened before. And in 2020, we expect to release fully compliant standard implementations in one year with the release of the standard, which has never happened before either. This is only for the benefit of the entire market - developers, users, teachers.
And also note that since we started to adhere to this approach, we have begun to do more (if we evaluate by large, medium and small features) and with higher quality (if we estimate by strictly reducing the number of bug reports and comments to draft of each standard). Although we ship what we managed to prepare (and if we didn’t manage something, we don’t ship it).
How seriously do you take approach (2)? If, in the opinion of an authoritative member of the committee, some big feature is “almost ready”, then you will be tempted to wait a bit, right?
We take it very seriously, and no.
We have statistics: in 2016 in Jacksonville, when we were finally determined with features for C ++ 17, Bjarne Stroustrup made a plenary meeting with a proposal to include concepts in C ++ 17. When they did not reach consensus, Straustrup was directly asked if he wanted to delay the release of C ++ 17 for a year in order to include concepts in it. Björn answered “no” without hesitation and twisting, and added that C ++ 17 without concepts is more important than C ++ 18 or C ++ 19 with concepts, although Straustrup has worked on them for about 15 years. The choice was: (2) release C ++ 17 without concepts, and then C ++ 20 with concepts (which we did), or (1) rename C ++ 17 to C ++ 20, which is isomorphic (2) with the exception of skipping C ++ 17 and refusing to release what was already ready for C ++ 17.
What about a compromise between (1) and (2)? Say, we usually stick to (2), but with “small” flexibility in terms, in order to get “some” extra time if you need to refine the feature?
No, because it will (1).
Fred Brooks in
The Mythical Man-Month popularly explained about the “mythical little transference” and concluded: “
Do not allow any small translations ”.
Imagine that we transferred C ++ 20. We would have to return from (2) to (1), regardless of how much we try to avoid it, and at the same time would not receive any benefits. If we decided to postpone C ++ 20 to polish it, then we would delay the standard for at least two years. There are no such concepts as transferring one or three meetings, because during this time others will continue (rightly) to say: “well, my feature just needs another meeting, we still have postponed, let's transfer one more”. And if we transfer at least for two years, it means that C ++ 20 becomes C ++ 22, and most likely C ++ 23 ... but we are already going to ship C ++ 23! - That is, in any case, we will ship C ++ 23, and the only difference is that we
do not transfer C ++ 20 with a large amount of work done, ready for release, and do not make the whole world wait another three years. Delay will not benefit these features, most of them or all together.
Therefore, the sentence is equivalent to “let's turn C ++ 20 into C ++ 22 or C ++ 23”, and a simple answer to it: “Yes, we will have C ++ 23, but in addition to C ++ 20, but not in its stead. ” A delay of C ++ 20 means the omission of C ++ 20 instead of releasing a good, stable, finished product, and there will be no benefit from this.
But feature X is broken / needs more time than we have to fix bugs in C ++ 20!
No problem! We can just cut it.
In this case, someone will need to write a letter describing the situation to the EWG or LEWG (depending on the situation), and offer to remove the feature from the working draft IS. These groups will consider the appeal, and if they decide that the feature is broken (and the plenum will agree with them), they will postpone the feature until the next C ++ release. We have already done so with the C ++ 0x concepts.
But in the case of (1), we will transfer not only this feature, but the
entire feature
set from C ++ 20 to C ++ 23! It would be ... bust.
Approach (2) means "major / minor" releases?
Not. At first, we said so, until we realized that (2) only means that you do not need to choose a set of features, even from the point of view of a “main / secondary” release.
Approach (2) means only “ship what is ready”. Releases are obtained:
- the same size (that is, usually medium) for smaller features, because less time is spent on their development (say, less than three years on each), and in general we get the same number of completed features in the release;
- and variable size (not once) for the “bigger” features, which take more time (say, more than three years for each), and each IS release includes as many of these features as they manage to complete for release. Therefore, in some releases there are more, in others less.
C ++ 14 and C ++ 17 were relatively small, because a lot of standardization efforts were spent on the long-running features described in the implementation proposals (for example, contracts) and the feature branches in TS (for example, concepts).
C ++ 20 is a big release ...
Yes. In C ++ 20, there are many large features. Three of the largest begin with “ko” (concepts, contracts, cortinis), so we could call it co_cpp20. Or co_dependent.
... and hasn't too much been done in a three-year cycle for C ++ 20?
No, see above, “once at a time is not necessary”.
C ++ 20 is big, not because we have done more in three years, but because there have been a lot of long development (including at least two, on which we have been working in the current form since 2012 in the form of P-sentences and TS branches) ) reached the stage of readiness and decided to include them in the IS draft of the same release.
Almost always, the main features are developed for many years. The main difference between approach (1) for C ++ 98 and C ++ 11 and approach (2) is that C ++ 98 and C ++ 11 delayed the release until all these features were ready, and now we ship large as ready, and along with them we release much more.
C ++ 20 went through the same three-year cycle as C ++ 14 and C ++ 17. We have not done more than the previous two cycles in the last three years, we just finished more basic features. If some of them were not ready, then we would have thrown it out and completed it already for C ++ 23. If this happens, we will inform about it in the proposal for implementation and explain the reasons.
C ++ 14 + 17 + 20 made up our third nine-year cycle (2011-2020) after C ++ 98 (1989-1998) and C ++ 11 (2002-2011). But since we adhered to approach (2), we
also released developments that were ready for the end of the three-year and six-year cycles.
Isn't it better to catch bugs when the product is in development, and not after it is released?
Of course better.
But if we are talking about the reasons for the delay in the release of the C ++ standard, this question implies two false assumptions:
- that before the standard was released, the features did not come out and were not used (many already have experience using in production);
- and that all features can be used together until the standard is released (not allowed).
I explain:
- Most of the major C ++ 20 features were implemented in the form in which they are reflected in the current draft of the standard, in at least one compiler, and in most cases were already used in the production code (that is, they are already available to users who are very satisfied) . For example, coroutines (implemented just five months before this article) were used for two years in production at MSVC and for a year at Clang, which turned out to be very welcome for large customers (for example, Azure and Facebook).
- We are not going to catch many problems of interaction of features until users start using them in production, that is, before the standard is released, because many developers will wait for it to be released in order to implement different projects. And if we show uncertainty about the timing of the release, then these implementations will also be delayed. Well, they are still implementing something, but a lot will be paused until the developers are sure that we are ready to release. Ask the creators of <compiler name> what happened when they implemented <nickname> before it appeared in the published standard. In many cases, it is necessary to sell repeatedly, and to break off consumers, too, repeatedly. Therefore, developers prefer to wait for the committee to approve certain features.
Finally, do not forget about the problem of the interaction of features. We not only release them when we are ready, after that we still need time to look for interaction problems between features and to add support for such interactions, which we simply cannot find out before new features become widely used. And it does not matter how far we delay the release of the standard, there will always be interactions that we will be able to explore only much later. This risk should be managed with the help of flexible design ensuring compatibility of features, rather than waiting for all risks to be eliminated.
The standard will never be perfect ... will you not make mistakes?
Yes.
If we see that the feature is not ready, then we must remove it from the release.
If we see that the feature can be better, and we know that the change may turn out to be backward compatible, then this is not a reason to refuse to release it now. It can be released as an extension in the following C ++.
We intentionally release features that we plan to improve in the future, while we are sure that we can maintain backward compatibility.
But shouldn't you try to minimize errors in releases?
Yes. We are trying.
But we do not try to avoid all risks. There is also a risk and (possible) price of not releasing what seems ready to us. And most often we are right.
Are you sure that now the quality is better than using approach (1)?
Yes.
According to objective metrics, the volume of comments from different countries and error reports, C ++ 14 and C ++ 17 were our most stable releases, and according to these metrics, they exceeded C ++ 98 and C ++ 11 by 3-4 times. And the reason is precisely the regularity of releases, the placement of large features first in TS branches (including full descriptions of their integration with the main standard) and their subsequent infusion when we are convinced of readiness.
Since 2012, the main standard
has always been maintained in an almost-ready-to-ship state (so that even working drafts are of the same high quality as releases of the C ++ 98 and C ++ 11 standards). This has never happened before, when for a long time we kept the patient unstitched, with long lists of problems and organs spread out around, which we are going to shove back soon. Now we know that we can withstand the schedule with high quality work, because we always remain in a state of close readiness for release. If they wanted to, they could have released a CD even now, without meeting in Cologne, and still the quality would be much higher than ever with CD C ++ 98 or C ++ 11 (in truth, and their published standards) . And considering that C ++ 98 and C ++ 11 were successful, the understanding that quality is now even higher means that we are on the right track.
C ++ 98 and C ++ 11 were developed for about 9 years and were very good products ...
Yes: 1989-1998 and 2002-2011.
... and C ++ 14 and C ++ 17 were minor releases. C ++ 20 is the main release?
I repeat, I think it is right to compare C ++ 14 + 17 + 20 as a single whole: this is our nine-year cycle, but since we followed approach (2), we also released some developments that were ready for the completion of the three-year and six-year cycles .
Does approach (2) allow achieving feature-based goals like P0592 for the next C ++?
Of course! While there are no words in it like “should include these features”, because then it will be an approach (1).
Striving for a certain set of features and giving priority to one of them is normal, but then it is a matter of priority. For now, we will only take what is ready, but we can choose what to work on first of all in order to prepare as soon as possible.