c++ - 如何确保某些代码被优化掉?
问题描述
tl;dr:是否可以以某种方式(例如通过编写单元测试)确保某些东西被优化掉,例如整个循环?
确保生产构建中不包含某些内容的常用方法是用#if...#endif
. 但我更喜欢继续使用 C++ 机制。即使在那里,我喜欢保持简单的实现而不是复杂的模板专业化,并争辩说“嘿,编译器无论如何都会优化它”。
上下文是汽车中的嵌入式软件(二进制大小很重要),编译器通常很差。它们在安全方面经过认证,但通常在优化方面并不出色。
示例 1:在容器中,元素的销毁通常是一个循环:
for(size_t i = 0; i<elements; i++)
buffer[i].~T();
这也适用于内置类型,例如int
,因为标准允许显式调用析构函数也适用于任何标量类型 (C++11 12.4-15)。在这种情况下,循环什么都不做并且被优化了。在 GCC 中是这样,但在另一个(Aurix)中不是,我在反汇编中看到了一个字面上的空循环!所以这需要一个模板专业化来修复它。
示例 2:仅用于调试、分析或故障注入等的代码:
constexpr bool isDebugging = false; // somehow a global flag
void foo(int arg) {
if( isDebugging ) {
// Albeit 'dead' section, it may not appear in production binary!
// (size, security, safety...)
// 'if constexpr..' not an option (C++11)
std::cout << "Arg was " << arg << std::endl;
}
// normal code here...
}
我可以看看拆解,当然。但作为上游平台软件,很难控制所有可能使用的目标、编译器及其选项。由于任何原因,下游项目存在代码膨胀或性能问题,这种担忧很大。
底线:是否有可能以某种方式编写软件,即已知某些代码会以一种安全的方式被优化掉#if
?或者一个单元测试,如果优化不符合预期,它会失败?
[第一个问题我想到了时序测试,但是作为裸机我还没有方便的工具。]
解决方案
if constexpr
是此类测试的规范 C++ 表达式(自 C++17 起)。
constexpr bool DEBUG = /*...*/;
int main() {
if constexpr(DEBUG) {
std::cerr << "We are in debugging mode!" << std::endl;
}
}
如果DEBUG
为 false,则打印到控制台的代码根本不会生成。因此,如果您有诸如检查代码行为所需的日志语句之类的东西,但您不想在生产代码中与之交互,则可以将它们隐藏在if constexpr
表达式中,以便在代码移动到后完全消除代码生产。
推荐阅读
- go - 字符串类型声明与字符串不可比较
- ios - 是否有每个控件/视图的所有 UIApperance 特征的列表?
- javascript - 重绘函数不是重绘每个对象
- c# - AWS Kinesis .NET 消费者
- c++11 - insert() 中的分段错误,C++ 上的双向链表
- node.js - 节点 oracledb 执行 pl/sql 函数
- c# - Etag 的每个组合都被视为无效。当我在图形资源管理器中执行相同的请求时,它可以工作
- python - 如何阅读python文档?
- python - 将 Python 连接到 MySQL 数据库
- activeadmin - 活动管理员在唯一字段上创建附加 URL