In my understanding, standard library is a whole separate piece of software than a compiler is. In my opinion, they should be kept separate.

Advantages of this approach pretty much boil down to "they can evolve independently".


  • Some standard library features could be rewritten in more modern core language features to be more consistent. Sometimes it can lead to huge benefits aside from being consistent. Examples can be most of the algorithms in <algorithm> header when ranges arrive. And pretty much any template when concepts arrive.

  • As standard library uses core language features, sometimes it might be hard to "synchronize them", to follow one pattern and not diverge. Also it could create a feature race, e.g. a feature from core language and a feature from standard library that do mostly the same thing might be rivaling each other to get into the standard. An example can be structured binding. Non declarations are not allowed to be a structured binding expression, because std::tie() does the same thing and it is considered that allowing non declaration binding would unnecessarily complicate things. To reach the conclusion, it required some research and time.

  • Some features simply get into in a broken state (may be they were not broken prior to inclusion). An example can be I/O facilities. Now that core language has template parameter packs, it could be possible to write printf() like functions and have type safety as well. There is an implementation of it, called fmt (Disclaimer: I'm not affiliated with them in any way nor have I used it extensively). Also the synchronization with C I/O library is no longer needed.

There might be more, but those are the only ones that were on top of my head.

So, the question is: why standard comittee chose to slowly fuse standard library and core language? Why were not std::tuple<> and std::initializer_list<> (and some other features) added to the core language instead?

An example of fusing is (in)famous conversion to std::initializer_list<>.

e.g.: auto indices{0, 1, 6, 9}; will result in std::initializer_list<int>.

Also, structured binding:

for (const auto& [key, value]: map) {...} will work even though std::pair is a standard library feature.

  • Could it be because the parser must change? Commented Jun 26, 2017 at 17:32
  • @FrankHileman, I believe it was only issue with folding expressions, I don't remember that being an issue with the features listed above. Commented Jun 26, 2017 at 17:34
  • 3
    Why would you want them to "evolve independently"? What benefit does that bring?
    – Caleth
    Commented Jun 27, 2017 at 12:13
  • @Caleth, they can be tested independently, and merged into the standard when they are ready. Also, bug fixes can come asynchroniously. Commented Jun 27, 2017 at 12:20
  • 2
    @Incomputable: "std::pair<>'s layout doesn't have to be the same" Actually, that's not true. std::pair is required by the standard to be a struct with publicly accessible members first and second, in that order. As such, it is required to be able to work with structured binding, without having to use the get/tuple_element interface. Commented Jun 29, 2017 at 19:19

4 Answers 4


I don't think there's really any change here.

There have been a few parts of the compiler that required knowledge of the standard library since the very beginning of C++ (well, maybe not the very beginning, but well before the standard anyway).

For example, a number of expressions (e.g., new expressions and dynamic_cast) can throw exceptions whose types are defined in the standard library. Some other expressions can end up calling abort.

The committee does seem to try to keep this sort of thing to a minimum--they only seem to do so when there's strong motivation and seems to be very little other reasonable route to achieving a goal.


It is my understanding that the C++ standards committee follows the rule that anything which can be efficiently implemented in a library, shall be. This policy exists to keep the C++ compilers from becoming more complex than absolutely necessary, and also minimizes the need to introduce new reserved words into the C++ language itself.

C++ is already one of the most difficult programming languages to correctly parse, so anything which makes it more complex only makes the process of ensuring compilers actually parse the language correctly and generate correct code even more difficult than it already is.

Keeping the core C++ language as simple as possible also keeps the task of porting existing implementations of the language to new platforms as simple as possible.

Writing a new C++ compiler from scratch is already a very non-trivial task.


Have a look at Swift. You can do absolutely nothing without the Swift Standard Library, because even things like integers, booleans and so on and their operations are part of the standard library, not part of the language. And that's Ok. It's because there are language and standard library, and together they produce an implementation. (Even 1 + 2 cannot be compiled using the language only).


C and C++ may be used to write code for things like thermostat controllers, blinkie-light toys, and other devices that don't have any kind of console, file system, or other such features, and may only have a few hundred bytes of RAM available, if that (the code itself is often stored in read-only memory or flash). While it's useful to have the Standard specify how things like console and file I/O should work, there's no reason the language shouldn't be usable to perform tasks that don't require such things, on platforms that don't support them. Separating the libraries from the language makes it easier to identify what parts of the language are "fundamental", and which parts need not be supported on freestanding implementations for platforms where they wouldn't be meaningful or useful.

  • 1
    You kind of missed an important point here. On some platforms (microcontrollers), it may be necessary to provide alternative (and likely trimmed down) implementations of the standard lib. In my mind, it’s less about “I don’t need that” and more about “That implementation doesn’t work well for this use case, I need to flexibility to provide an appropriate one.”
    – RubberDuck
    Commented Nov 27, 2019 at 10:46
  • 1
    @RubberDuck: That's the point I was trying to make. The Standard is intended to make the language flexible to a wide range of purposes, though I think it errs in simultaneously requiring too much (e.g. floating-point with longer than 32 bit significand, which doubles the cost of math on many processors without floating-point) but not allowing enough means by which implementations can indicate what constructs they do or do not usefully support.
    – supercat
    Commented Nov 27, 2019 at 15:26

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.