从 C++ 文件中删除无用的行

2024-05-08

很多时候,当我调试或重用某些代码时,文件开始获取不执行任何操作的行,尽管它们可能在某一时刻执行了某些操作。

像向量和填充然后不再使用之类的东西,定义但从未使用的类/结构,以及声明但从未使用的函数。

我知道在很多情况下,其中一些东西并不是多余的,因为它们可能从其他文件中可见,但就我而言,没有其他文件,只有我的文件中的无关代码。

虽然我理解从技术上讲,调用push_back做了一些事情,因此向量本身并没有被使用,在我的例子中,它的结果未被使用。

那么:有没有办法做到这一点,无论是使用编译器(clang、gcc、VS 等)还是外部工具?

Example:

#include<vector>
using namespace std;
void test() {
    vector<int> a;
    a.push_back(1);
}
int main() {
    test();
    return 0;
}

应该变成:int main(){return 0};


我们的 DMS 软件重组工具包及其 C++11 前端可用于执行此操作;目前它还没有现成的功能。 DMS 旨在为任意源语言提供自定义工具构建,并包含完整的解析器、名称解析器和各种流分析器来支持分析,以及根据分析结果对代码应用源到源转换的能力。

一般来说,您需要一个静态分析来确定是否使用每个计算(结果,可能有多个,仅考虑“x++”)。对于每个未使用的计算,实际上您希望删除未使用的计算,然后重复分析。出于效率原因,您希望进行一次分析,一次性确定结果的所有(点)使用情况;这本质上是一个数据流分析。当计算结果的使用集变空时,可以删除该计算结果(注意删除“x++”值结果可能会留下“x++”,因为仍然需要增量!)以及它所依赖的计算的使用集可以进行调整以从已删除的引用中删除引用,这可能会导致更多的删除。

要对任何语言进行此分析,您必须能够跟踪结果。对于 C(和 C++)来说,这可能非常难看;在表达式中使用计算结果以及将其分配给本地/全局变量(在其他地方使用)时存在“明显”用途,并且存在通过指针、对象字段更新、通过任意强制转换的间接分配等等。要了解这些影响,您的死代码分析工具必须能够读取entire软件系统,并计算其中的数据流。

为了安全起见,您希望该分析是保守的,例如,如果该工具没有证据表明结果未被使用,那么它必须假设该结果被使用;您通常必须使用指针(或数组索引,它们只是伪装的指针)来执行此操作,因为通常您无法精确确定指针“指向”的位置。显然,可以通过假设使用所有结果来构建一个“安全”工具:-}有时您还会对没有源代码的库例程做出非常保守但必要的假设。在这种情况下,拥有一组库副作用的预先计算的摘要会很有帮助(例如,“strcmp”没有副作用,“sprintf”覆盖特定操作数,“push_back”修改其对象......)。由于库可能非常大,因此这个列表也可能非常大。

DMS 通常可以解析整个源代码库、构建符号表(因此它知道哪些标识符是本地/全局标识符及其精确类型)、进行控制和本地数据流分析、为每个函数构建本地“副作用”摘要、构建调用图形和全局副作用,并进行全局点分析,以适当的保守性提供此“使用的计算”信息。

DMS 已用于在 2600 万行代码的 C 代码系统上执行此计算(是的,这是一个非常大的计算;它需要 100Gb VM 才能运行)。我们没有实现死代码消除部分(该项目有另一个目的),但一旦有了这些数据,这就很简单了。 DMS 通过更保守的分析对大型 Java 代码进行了死代码消除(例如,“没有提及标识符”,这意味着对标识符的赋值是死的),这导致许多实际代码中的代码删除量惊人。

DMS 的 C++ 解析器目前可以构建符号表,并可以对 C++98 进行控制流分析,C++11 也即将推出。我们仍然需要本地数据流分析,这需要一些努力,但全局分析已经存在于 DMS 中,并且可用于实现此效果。 (如果您不介意更保守的分析,可以从符号表数据中轻松获得“不使用标识符”)。

在实践中,您不希望该工具只是默默地把东西撕掉;有些实际上可能是您希望保留的计算。 Java 工具的作用是产生两个结果:死计算列表,您可以检查这些计算以确定您是否相信它,以及源代码的死代码删除版本。如果您相信死代码报告,则保留已删除死代码的版本;如果您看到一个您认为不应该死的“死”计算,您可以修改代码以使其不死,然后再次运行该工具。对于庞大的代码库,检查死代码报告本身可能很困难; “你”如何知道你的团队中的“其他人”是否不重视某些明显无效的代码? (如果你出错了,可以使用版本控制来恢复!)

我们没有(而且我知道没有任何工具)处理的一个非常棘手的问题是条件编译存在时的“死代码”。 (Java 不存在这个问题;C 确实有这个问题,C++ 系统则更少)。这确实很糟糕。想象一个条件,其中一个手臂有某些副作用,而另一个手臂有不同的副作用,或者另一种情况,其中一个手臂由 GCC 的 C++ 编译器解释,而另一个手臂由 MS 解释,并且编译器对构造的作用存在分歧(是的,C++ 编译器在黑暗角落确实不同意)。充其量我们可以在这里非常保守。

CLANG有一定的流量分析能力;以及一些进行源转换的能力,因此它可能被迫这样做。我不知道它是否可以进行任何全局流量/指向分析。它似乎偏向于单个编译单元,因为它的主要用途是编译单个编译单元。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

从 C++ 文件中删除无用的行 的相关文章

  • IIS应用程序池回收+quartz调度

    我正在 IIS 7 5 上运行一个 Web 应用程序 它需要偶尔回收 否则内存使用情况会失控 这是我正在研究的问题 当它回收时 它实际上不会运行 直到另一个请求到来 而quartz不会运行 有没有办法让IIS在回收应用程序池后立即自动启动1
  • CMake 找不到请求的 Boost 库

    既然我已经浏览了其他人的解决方案几个小时 但找不到适合我的问题的正确答案 我想将我的具体问题带给您 我正在尝试使用 CMake 构建 vsomeip 为此 我之前构建了 boost 1 55 但是 我在 CMake 中收到以下错误 The
  • 单元测试验证失败

    我正在运行我的单元测试PostMyModel路线 然而 在PostMyModel 我用的是线Validate
  • 在 OnModelCreating 期间设置列名称

    Issue 我目前正在尝试通过设置的属性为我的表及其列添加前缀 我正在使用实体框架核心 我已经正确地为表名添加了前缀 但我似乎无法弄清楚列的前缀 我有一种感觉 我需要使用反射 我已经留下了我的 可能很糟糕的 反思尝试 有人有办法在实体中设置
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 如何使用 SOAP 且不使用 WSE 在 .NET 中签署 Amazon Web 服务请求

    亚马逊产品广告 API 以前称为 Amazon Associates Web Service 或 Amazon AWS 实施了一项新规则 即自 2009 年 8 月 15 日起 向其发送的所有 Web 服务请求都必须经过签名 他们在其网站上
  • 在 omp 并行 for 循环中使用 unique_ptr 会导致 SEG.FAULT

    采取以下代码 include
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 访问 ascx 文件中的母版页控件

    我有一个母版页文件 其中包含 2 个面板控件中的 2 个菜单 我还使用控件来检查用户是否登录并获取用户类型 根据我想要显示 隐藏面板的类型 控件本身不在母版页中引用 而是通过 CMS 系统动态引用 我想在用户控件中使用findcontrol
  • 使用查询表达式对 List 进行排序

    我在使用 Linq 订购这样的结构时遇到问题 public class Person public int ID get set public List
  • C# 编译器不会优化不必要的强制转换

    前几天 在写答案的时候这个问题 https stackoverflow com questions 2208315 why is any slower than contains在这里 关于溢出 我对 C 编译器感到有点惊讶 它没有按照我的
  • 将接口转换为其具体实现对象,反之亦然?

    在 C 中 当我有一个接口和几个具体实现时 我可以将接口强制转换为具体类型 还是将具体类型强制转换为接口 这种情况下的规则是什么 Java 和 C 中都允许这两个方向 向下转型需要显式转型 如果对象类型不正确 可能会抛出异常 然而 向上转换
  • Linux mremap 不释放旧映射?

    我需要一种方法将页面从一个虚拟地址范围复制到另一个虚拟地址范围 而无需实际复制数据 范围很大 延迟很重要 mremap 可以做到这一点 但问题是它也会删除旧的映射 由于我需要在多线程环境中执行此操作 因此我需要旧映射能够同时使用 因此稍后当
  • 选择查询不适用于使用Parameters.AddWithValue 的参数

    C 中的以下查询不起作用 但我看不出问题所在 string Getquery select from user tbl where emp id emp id and birthdate birthdate cmdR Parameters
  • 使用 jQuery 从 ASP.Net JSON 服务获取数据

    我正在尝试调用 Google 地图地理编码 API 从纬度 经度对中获取格式化的地址 然后将其记录到控制台 我正在尝试获取为给定位置返回的第一个 formatted address 项目 我很简单无法从 JSON 中提取该项目 我不知道为什
  • 如何在 winforms 应用程序的主屏幕显示之前显示欢迎屏幕?

    我想在应用程序启动时加载欢迎屏幕 然后用户单击欢迎屏幕上的按钮 然后关闭欢迎屏幕 最后显示主屏幕 static void Main startup method being called Application EnableVisualSt
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 来自 3rd 方库的链接器错误 LNK2019

    我正在将旧的 vc 6 0 应用程序移植到 vs2005 我收到以下链接器错误 我花了几天时间试图找到解决方案 错误LNK2019 无法解析的外部符号 imp 创建AwnService 52 在函数 public int thiscall
  • 如何使用placement new重新初始化该字段?

    我的课程包含字段 private OrderUpdate curOrderUpdate 我一遍又一遍地使用它 经常需要重新初始化 for int i 0 i lt entries size i auto entry entries i ne
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc

随机推荐

  • 在单个命令中使用前缀重命名文件夹中的所有文件

    重命名带有前缀的文件夹中的所有文件 Unix 假设一个文件夹有两个文件 a txt b pdf 那么它们都应该从一个命令重命名为 Unix a txt Unix b pdf 如果您的文件名包含没有空格并且你没有任何子目录 你可以使用一个简单
  • 从 django 返回带有 BOM 的 UTF-8 编码的 csv

    我正在尝试输出一个用户可以用 Excel 打开的 CSV 文件 我已经用 UTF 8 编码了所有字符串 但是当我用 Excel 打开文件时 我看到了乱码 只有在将文件转换为带 BOM 的 UTF 8 在 Windows 上使用 notepa
  • 如何使用spring data mongodb在mongodb中创建视图

    如何使用spring data mongodb在mongodb中创建视图 谢谢 您可以在需要的地方注入 org springframework data mongodb core MongoTemplate 类型的 bean 并使用其方法之
  • 从两个字典创建一个新列表

    这是一个关于Python的问题 我有以下字典列表 listA t 1 tid 2 gtm 3 c1 4 id 111 t 3 tid 4 gtm 3 c1 4 c2 5 id 222 t 1 tid 2 gtm 3 c1 4 c2 5 id
  • 提高 pytesseract 从图像中正确识别文本的能力

    我正在尝试使用读取验证码pytesseract模块 大多数时候它都能提供准确的文本 但并非总是如此 这是读取图像 操作图像以及从图像中提取文本的代码 import cv2 import numpy as np import pytesser
  • 匹配模式引用或取消引用值之间有什么区别吗?

    Clippy https github com rust lang nursery rust clippy对这样的代码发出警告 fn func
  • C++ 将枚举值捕获为异常

    我正在尝试使用external C 库将其异常定义为 enum MY ERRORS ERR NONE 0 ERR T1 ERR T2 然后在代码中抛出异常是这样的 if throw ERR T1 作为 C 编程新手 我会这样做 try ca
  • 是否有适用于 SaaS 或订阅的 Schema.org 类型?

    我们销售按月订阅的软件即服务 我试图弄清楚我们是否可以通过 Schema org 的规范提供元数据 我一直在考虑products https developers google com structured data rich snippe
  • 有没有由 HTML + css + javascript 驱动的 sql 编辑器? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 语法高亮 sql代码格式 代码镜像 http codemirror net 会成功的 这太好了 非常容
  • @monthly cron 作业不可靠

    我们的客户希望我们每月创建一份报告 过去 我们使用 monthly cron 作业来完成此任务 但这并不可靠 服务器可能会在这一分钟内宕机 Cron 不会重新运行这些作业 如果服务器已启动 此时数据库可能无法访问 如果服务器已启动且数据库已
  • 无法导入@material-ui/core/styles/MuiThemeProvider

    我正在开发一个 React 项目 使用 Material UI React 组件 我想进口MuiThemeProvider in src index js像这样import MuiThemeProvider from material ui
  • 如何在流星模板中设置日期格式

    我需要以 mm dd yyyy 格式显示数据库中的日期 因为它以 ISO 格式保存在mongodb如何在模板中转换它 这是我的代码 Template templatename vname function return Posts find
  • MuiThemeProvider:如何为不同的路线使用不同的主题?

    我需要根据网站的当前部分稍微更改主题 看起来MuiThemeProvider仅套muiTheme负载 但当 props 改变时需要更新 如何才能做到这一点 您可以尝试将主题放入包装组件中 以保持主题的状态 使用React 的上下文 http
  • 想要从 beanIO 字段名称标签在 csv 中写入标题

    我想在 csv 文件中写入标题 因为我的文本文件不包含任何标题 所以我想从 beanIO 字段名称标签写入它 我有一个 beanIO 有两个流 一个用于读取 另一个用于写入 这是输入文件 文本输入 txt 1 约翰 露 BA xxx1萨姆
  • C++ while 循环优化无法正常工作

    我有这个代码段 include
  • 在 EXCEL 中使用多个表的条件求和

    我有一个表 我试图根据两个参考表的值来填充该表 我有各种不同的项目 类型 1 类型 2 等 每个项目运行 4 个月 并且根据其生命周期的不同时间 花费不同的金额 这些成本计算显示在Ref Table 1 参考表1 Month a b c d
  • 是否可以使用 php 中的 C++ 二进制文件

    是否可以编写一些 C 或 C 代码并编译为二进制文件 然后将这些二进制文件与 php 一起使用 是否也可以使用 C 和 C 编写 php 库 如果是这样 请告诉我该怎么做 PHP 在设计上是模块化的 它由 引擎 和许多扩展组成 其中一些是必
  • Dojo DataGrid (DGrid) 添加复选框列

    我在用DojoDgrid 但是我正在尝试添加一个复选框列 但我不确定该方法 我一直在看的大多数教程都遵循不同的代码结构 我无法创建复选框列 我想创建一个复选框列来选择行 Code 这里还有一个Fiddle http jsfiddle net
  • CodingBat sum67:为什么这个解决方案是错误的?

    我正在解决以下codingbat问题 返回数组中数字的总和 但忽略以 6 开头并延伸到下一个 7 的数字部分 每个 6 后面至少有一个 7 如果没有数字则返回 0 sum67 1 2 2 5 sum67 1 2 2 6 99 99 7 5
  • 从 C++ 文件中删除无用的行

    很多时候 当我调试或重用某些代码时 文件开始获取不执行任何操作的行 尽管它们可能在某一时刻执行了某些操作 像向量和填充然后不再使用之类的东西 定义但从未使用的类 结构 以及声明但从未使用的函数 我知道在很多情况下 其中一些东西并不是多余的