C++ 零开销原则有哪些重要的例外情况(如果有的话)?

C++ 零开销原则有哪些重要的例外情况(如果有的话)?,c++,C++,作为一个(可能的)示例,LLVM编码标准禁止使用标准RTTI或例外: 这是一个好主意,还是编码标准对大多数程序来说已经过时或不合理 P> C++中有没有其他这样的特征,即使程序不使用,也会显著地影响程序的速度、内存使用或可执行大小? 这仍然是一个好主意,还是那个编码标准已经过时了 RTTI无疑是最臭名昭著的违反零开销原则的行为,因为它产生的静态成本(可执行文件大小和初始化代码)与多态类的数量(即至少有一个虚拟函数的类)成正比,并且它不取决于您使用它的数量(如果有的话)。但是,如果没有一些每类

作为一个(可能的)示例,LLVM编码标准禁止使用标准RTTI或例外:

这是一个好主意,还是编码标准对大多数程序来说已经过时或不合理

<> P> C++中有没有其他这样的特征,即使程序不使用,也会显著地影响程序的速度、内存使用或可执行大小? 这仍然是一个好主意,还是那个编码标准已经过时了

RTTI无疑是最臭名昭著的违反零开销原则的行为,因为它产生的静态成本(可执行文件大小和初始化代码)与多态类的数量(即至少有一个虚拟函数的类)成正比,并且它不取决于您使用它的数量(如果有的话)。但是,如果没有一些每类开销,就无法真正提供RTTI。这就是为什么如果你根本不需要RTTI,或者如果你想用一个你有更多控制权的RTTI系统来代替它,你可以在大多数编译器上禁用RTTI(就像LLVM的家伙那样)。然而,如果您启用了RTTI,并且没有使用它,那么开销仅以代码膨胀(更大的可执行文件、更大的内存空间、更大的代码扩展)和加载/卸载时间的形式存在,因此,运行时执行开销几乎不存在。但在资源匮乏的环境中,或者对于小型实用程序(例如,在shell脚本中重复调用),静态开销可能太大而无法承受。此外,在很多实际情况下,您并不需要高性能RTTI,大多数情况下您根本不需要它,而在其他情况下,您需要在一些特殊的地方使用它,与其他事情相比,这些地方的性能通常并不重要。LLVM在这里是一个例外,因为编写编译器涉及到处理抽象语法树和类似的描述性类层次结构,这在没有大量向下转换的情况下是很难做到的,而且由于分析这些结构是编译器的核心操作,向下转换(或其他RTTI调用)的性能至关重要。因此,不要将“不要使用RTTI”作为一般规则,只需知道它会带来什么开销,并知道它在成本/收益方面是否适合您的应用程序

当然,C++异常是下一个可能会比您准备讨价还价的开销更大的问题。这是一个更具争议性的问题,特别是当涉及到实际描述总体异常的开销时。根据经验评估异常的开销是一项非常困难的任务,因为它高度依赖于使用模式,也就是说,有不同的方法使用异常,不同的严重程度(您是否使用异常来处理bug、致命错误、异常情况,或者替换每个if语句?),对于错误处理有不同的注意级别(无论是否使用异常)。当然,不同的编译器可以实现不同的异常。当前的实现,即所谓的“零成本异常”,旨在使正常执行期间的运行时成本为零,但这会留下相当多的静态开销,并使throw-to-catch执行路径变慢。这是一个很好的概述。至于违反“你只为你使用的东西付费”原则的例外情况,这是正确的(除非你禁用它们),但它们通常是合理的。对于异常的基本假设是,作为一名程序员,您打算编写健壮的错误处理代码,如果您确实适当地处理了所有错误,那么异常的开销将与错误处理代码(捕获块和析构函数)相比显得微不足道,您可能会有一个比同等数量错误处理的C风格错误代码实现更小更快的程序。但是,如果您不打算做很多错误处理(例如,“如果出现任何错误,请崩溃!”方法),那么异常将产生巨大的开销。我不太清楚为什么LLVM禁止异常(如果我不得不直言不讳的话,我会说这是因为他们对错误处理并不认真,从我在该项目中看到的代码来看)。因此,长话短说,指导原则应该是“如果您打算认真处理错误,请使用异常,否则不要”。但请记住,这是一个激烈争论的话题

有没有其他违反“你只为你使用的东西付费”的功能

您已经命名了两个明显的特性,不足为奇的是,它们是大多数编译器都可以禁用的两个主要特性(并且通常在适当的时候禁用)。当然还有其他更轻微的违反零开销原则的行为

一个臭名昭著的例子是来自标准库的IO流库(
)。这个图书馆经常被批评为对于大多数人所需要和使用的东西有太多的开销。IO流库倾向于引入大量代码,并且需要相当多的加载时初始化。而且,它的许多类,如
std::ostream
std::ofstream
在构建/销毁和读/写性能方面都有太多的运行时开销。我认为他们在这个库中包含了太多的功能,而且由于大多数时候,IO流任务都非常简单,这些功能经常被闲置,它们的开销也不合理。但总的来说,我发现开销通常是可以接受的,特别是因为不管怎样,大多数IO任务已经非常慢了。顺便说一句,LLVM还禁止使用IO流库,这是因为LLVM的目标是编写执行大量文件IO的精简且平均的命令行实用程序(如编译器或其相关工具)

可能还有其他标准库的开销比某些特定情况下可能希望的要大。库代码