There are a number of standard libraries that we (Google) ban because we have in-house alternatives that we generally prefer. (In some cases, this is due to compatibility with our threading model. In others, it's probably due to inertia.)
From a skim: <chrono>, <filesystem>, <thread> (along with other concurrency libraries like <mutex> and <future>) are the main ones.
As far as language features that we ban, it's notable that we ban exceptions. Rvalue references are generally discouraged outside of well-trod paths (e.g. move constructors). We ban runtime type information (dynamic_cast, typeid, etc). There are some newer features in C++20 that we haven't accepted yet (modules, ranges, coroutines), due to lack of tooling, concerns about performance, and more.
Sometimes these bans get reversed (there was a long-standing ban on mutable reference parameters that was overturned after many years of discussion).
One of the key points we try to emphasize is that readability is primarily about reading other people's code, and so we provide well-trod paths that try to avoid pitfalls and generally surprising behavior (e.g. this article's focus on initialization? https://abseil.io/tips/88). There is value in moving closer to Python's "There should be one-- and preferably only one --obvious way to do it."
We assert that one of the goals of the style guide (the second section, after Background) is that rules should pull their own weight; we explicitly cite this as a reason why we don't ban goto. I imagine this is also why there isn't an explicit ban on alternative operator representations (e.g. writing `if (foo and bar) <% baz(); %>`).
I don't think I agree that every rule pulls its own weight -- I like to cite that I copy-pasted the internal version of the style guide into a Google doc earlier this year to see how long it was... and it clocked in at over 100 pages. But maybe that's an indicator of how complex C++ is, where we have to make the tradeoff between being concise, being precise, and providing sufficient context.
From a skim: <chrono>, <filesystem>, <thread> (along with other concurrency libraries like <mutex> and <future>) are the main ones.
As far as language features that we ban, it's notable that we ban exceptions. Rvalue references are generally discouraged outside of well-trod paths (e.g. move constructors). We ban runtime type information (dynamic_cast, typeid, etc). There are some newer features in C++20 that we haven't accepted yet (modules, ranges, coroutines), due to lack of tooling, concerns about performance, and more.
Sometimes these bans get reversed (there was a long-standing ban on mutable reference parameters that was overturned after many years of discussion).
One of the key points we try to emphasize is that readability is primarily about reading other people's code, and so we provide well-trod paths that try to avoid pitfalls and generally surprising behavior (e.g. this article's focus on initialization? https://abseil.io/tips/88). There is value in moving closer to Python's "There should be one-- and preferably only one --obvious way to do it."
We assert that one of the goals of the style guide (the second section, after Background) is that rules should pull their own weight; we explicitly cite this as a reason why we don't ban goto. I imagine this is also why there isn't an explicit ban on alternative operator representations (e.g. writing `if (foo and bar) <% baz(); %>`).
I don't think I agree that every rule pulls its own weight -- I like to cite that I copy-pasted the internal version of the style guide into a Google doc earlier this year to see how long it was... and it clocked in at over 100 pages. But maybe that's an indicator of how complex C++ is, where we have to make the tradeoff between being concise, being precise, and providing sufficient context.