正统 C++
Orthodox C++

原始链接: https://bkaradzic.github.io/posts/orthodoxc++/

“正统 C++”(Orthodox C++)是一种编程哲学,主张使用 C++ 语言中极简且稳定的子集,以避免“现代 C++”带来的复杂性。支持者认为,许多语言特性(如异常、RTTI、流和过度的元编程)会引入不必要的运行时开销、隐性成本以及架构上的复杂性。 通过优先编写 C 程序员易于阅读的代码,“正统 C++”旨在构建更易于维护、高度可移植且兼容旧编译器的软件。这种方法不鼓励立即采用新标准,建议至少等待五年以确保稳定性及工具链的广泛支持。与其依赖繁重的抽象或 STL(尤其是那些会进行隐式内存分配的部分),“正统 C++”更推崇一种更手动、更显式的风格,并依赖于 `` 和 `` 等标准 C 库。 归根结底,这一哲学的目标是以简洁为重,而非追逐最新特性,从而确保项目保持易用性,并避免因混合 C 风格错误处理与复杂 C++ 运行时系统而产生的“割裂”。截至 2025 年,该社区已谨慎地批准了对 C++20 部分特性的选择性使用。

所提供的 Hacker News 讨论帖探讨了“正统 C++”(Orthodox C++)的概念,这是一种提倡简洁并避免复杂语言特性的编程风格。 社区对此文章的反应褒贬不一,凸显了围绕 C++ 最佳实践的持续争论。一些用户批评该风格过于教条,而另一些人则认为 `dynamic_cast` 和现代迭代语法等特性对于提高生产力至关重要,并认为“正统”方法并无助益。相比之下,一位评论者提出了“异端 C++”(Heterodox C++)的概念,这是一种截然不同的理念,主张利用函数式编程和大量的模板元编程来实现媲美 Rust 的安全性。 归根结底,这场讨论是整个 C++ 社区的一个缩影:社区分裂为倾向于使用语言中受限的类 C 子集的人,以及那些充分利用其最先进、最现代功能的人。正如一位参与者所指出的,共识在于:应避免僵化的教条,转而采取务实的开发态度。
相关文章

原文

This article was originally published as a gist here.

What is Orthodox C++?

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.

Why not Modern C++?

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).

d0pfbigxcaeip0m

Why use Orthodox C++?

“Within C++, there is a much smaller and cleaner language struggling to get out.” – Bjarne Stroustrup

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.

Hello World in Orthodox C++

#include <stdio.h>

int main()
{
    printf("hello, world\n");
    return 0;
}

What should I use?

  • 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).
  • Don’t use modules.

Using modules brings with it the following disadvantages:

  1. Need to rewrite (possibly refactor) your code.
  2. Loss of portability.
  3. Module binary files (with the exception of MSVC) are not portable so you need to provide header files for libraries in any case.
  4. The project build setup becomes more complicated.
  5. Any toolchain version except the newest one does not work (at the time of writing Apple’s module support is listed as “partial”)

In exchange for all this you, the regular developer-about-town, get the following advantages:

  1. Nothing.

Is it safe to use any of Modern C++ features yet?

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.

Revision History

UPDATE As of January 14th 2025, Orthodox C++ committee approved selective use of C++20.

Any other similar ideas?

Code examples

联系我们 contact @ memedata.com