Orthodox C++ (sometimes referred as C+) is minimal subset of C++ that improves C, but avoids all unnecessary things from so called Modern C++. It's exactly opposite of what Modern C++ suppose to be.
Back in late 1990 we were also modern-at-the-time C++ hipsters, and we used latest features. We told everyone also they should use those features too. Over time we learned it's unnecesary to use some language features just because they are there, or features we used proved to be bad (like RTTI, exceptions, and streams), or it backfired by unnecessary code complexity. If you think this is nonsense, just wait few more years and you'll hate Modern C++ too ("Why I don't spend time with Modern C++ anymore" archived LinkedIn article).
Code base written with Orthodox C++ limitations will be easer to understand, simpler, and it will build with older compilers. Projects written in Orthodox C++ subset will be more acceptable by other C++ projects because subset used by Orthodox C++ is unlikely to violate adopter's C++ subset preferences.
#include <stdio.h>
int main()
{
printf("hello, world\n");
return 0;
}
- C-like C++ is good start, if code doesn't require more complexity don't add unnecessary C++ complexities. In general case code should be readable to anyone who is familiar with C language.
- Don't do this, the end of "design rationale" in Orthodox C++ should be immedately after "Quite simple, and it is usable. EOF".
- Don't use exceptions.
Exception handling is the only C++ language feature which requires significant support from a complex runtime system, and it's the only C++ feature that has a runtime cost even if you don't use it – sometimes as additional hidden code at every object construction, destruction, and try block entry/exit, and always by limiting what the compiler's optimizer can do, often quite significantly. Yet C++ exception specifications are not enforced at compile time anyway, so you don't even get to know that you didn't forget to handle some error case! And on a stylistic note, the exception style of error handling doesn't mesh very well with the C style of error return codes, which causes a real schism in programming styles because a great deal of C++ code must invariably call down into underlying C libraries.
- Don't use RTTI.
- Don't use C++ runtime wrapper for C runtime includes (
<cstdio>
,<cmath>
, etc.), use C runtime instead (<stdio.h>
,<math.h>
, etc.) - Don't use stream (
<iostream>
,<stringstream>
, etc.), use printf style functions instead. - Don't use anything from STL that allocates memory, unless you don't care about memory management. See CppCon 2015: Andrei Alexandrescu "std::allocator Is to Allocation what std::vector Is to Vexation" talk, and Why many AAA gamedev studios opt out of the STL thread for more info.
- Don't use metaprogramming excessively for academic masturbation. Use it in moderation, only where necessary, and where it reduces code complexity.
- Wary of any features introduced in current standard C++, ideally wait for improvements of those feature in next iteration of standard. Example
constexpr
from C++11 became usable in C++14 (per Jason Turner cppbestpractices.com curator)
Due to lag of adoption of C++ standard by compilers, OS distributions, etc. it's usually not possible to start using new useful language features immediately. General guideline is: if current year is C++year+5 then it's safe to start selectively using C++year's features. For example, if standard is C++11, and current year >= 2016 then it's probably safe. If standard required to compile your code is C++17 and year is 2016 then obviously you're practicing "Resume Driven Development" methodology. If you're doing this for open source project, then you're not creating something others can use.
UPDATE As of January 14th 2022, Orthodox C++ committee approved use of C++17.
- Embedded C++
- Nominal C++
- Sane C++
- Why Your C++ Should Be Simple
- C++, it’s not you. It’s me.
- "Keep It C-mple" Alexander Radchenko Sydney C++ Meetup
- A dialect of C++
- Any C source that compiles with C++ compiler.
- DOOM 3 BFG
- Qt (when built with no-rtti, no-exceptions)
- dear imgui
- bgfx
- TheForge
- Oryol
- Network Next SDK
I mean yes, if you don't understand what a pointer is, you might misuse
unique_ptr
in such a way, even though unique_ptr is pretty clear on that...It seems to me like normal pointers also create the exact same "mess".
Uhhhh... I'm pretty sure they're actually transferring to a massive
union
w.r.t. thebase::Value
stuff...shared_ptr
has been banned from Chromium for quite a long time now, btw?????
Adding garbage collection was a bit stupid, yes. Format strings aren't exactly anything like it, though. GC was kind of useless because C++ is not a language made to be anywhere near that kind of stuff. Format strings are just a nice way to express how to format data, so there isn't much of a reason that they wouldn't be applicable to C++ just as much as to basically every other language.
std::regex
was a complete failure partly of its design and also because of its implementations. That doesn't mean the very idea of regexes is inapplicable to C++ lol.While WG21 isn't the compiler vendors and they thus aren't exactly responsible for Clang and MSVC not shipping freestanding C++ implementations, I do agree that they share some part of the blame in that freestanding is presently in a pretty bad state, and thus not actually very useful. In fact, I'd say P0829 is perhaps the best chance of Clang/MSVC finally giving a shit about freestanding - if the functionality offered in there is actually useful in a non-negligible way beyond what freestanding C already offers, they might bother working on it.
Just in case you're actually serious and believe this, I would clarify that I do not, in fact, think all C features are wrong, or even that
switch
is.While I do think having something like
-Wimplicit-fallthrough
on is pretty important for safety w.r.t. fallthroughs, and that it would have been nice for the language to perhaps have had a requirement for some kind offallthrough;
statement, I was only talking about it as an example of why your argumentation is obviously flawed.I say that it would be "easy enough" to test whether you've used something like
string_view
properly if you have at least one easily available toolchain that has the proposed features from P0829. I'm not saying that it would be "easy enough" to check whether your code works everywhere. I know how much of a pain it is to check whether the same software works everywhere (I've done similar things myself multiple times and it's why I have about 20 Windows and Linux/BSD distribution VMs ready to be fired up to test whether something works on them).I mean for sure WG21 deserves a bit of the blame on this, but it's quite clear that the issue isn't solvable in the standard unless you want to give up on
std::unique_ptr
for stupidly asinine reasons. That clang and libc++ are working towards solving this is great, though.Also, on exception optimization, while it's a bit complicated to do, it's not impossible: it's just that nobody has really bothered because unless you're using exceptions in an arguably pretty wrong way, you're not gonna need such optimization.
But that's not the issue that log4j had. The issue log4j had is essentially equivalent to if, say, doing
print("something '", userControlled, "'.\n")
with that fast_io library was vulnerable because it looks at all strings you give it to check if any of them contain${jndi:address}
and then connected toaddress
(thus basically giving control to whoever controls the server considering how fucked the protocol is). That's not a format string vulnerability. It's just an incredibly stupid way to specify something like this.