当我想问一个问题时,例如stackoverflow 我通常必须发布源代码。
问题是,我正在使用相当大的自定义框架、类结构等,并且与问题相关的部分可能位于许多地方(有时很难检测代码的哪些部分对问题很重要)。我无法发布完整的源代码(它太大而无法有效阅读)。
出于这个原因,我通常会努力编写最少的代码(通常在一个 main.cpp
中,而不是大量的类中)来重现问题。
我想知道 - 是否可以自动化该过程?
这里要做的典型事情是用它们的主体替换方法/函数的调用,将文件合并到一个.cpp
中,删除所有“未调用”的方法和类,未使用的变量等。
最佳答案
这里真正的困难在于区分“它没有做我想要的”、“错误消失了,因为我删除了基本代码”和“它现在崩溃了,因为我删除了一些重要的东西”。实际上,在将某些代码标记为“不需要”后按删除键是最简单的部分。
找出显示问题所必需的内容是困难的部分,并且很难将其自动化 - 因为有必要了解代码应该执行的操作与实际执行的操作之间的区别。只是随机删除代码是行不通的,因为"new"代码可能会被破坏,因为您删除了一些必要的步骤,而不是因为您删除了未使用的 CRUD - 只有[理解问题]的人才能做到这一点。
考虑一下:
Object* something;
void Initialize()
{
something = new Object(1, 2, 3);
}
int main()
{
Initialize();
// Some more code, some of which SOMETIMES sets something = NULL.
something->doStuff(); // Will crash if object is NULL.
}
如果我们删除Initialize
,代码每次都会失败,而不仅仅是每三次。但这是因为Object还没有初始化,而不是代码中的bug【可能是我们应该在something->doStuff()
之前添加if (something)
,或者因为我们不应该在“更多代码”中将其设置为 NULL
,所以“不要这样做”]。
当我处理一个棘手的问题时,尤其是在我们拥有自动生成代码以在不同条件下测试不同功能的测试系统的工作中,我的第一步是使[或采用一些现有]代码成为“小型独立测试” ,它小而简单,只做“必要的事情”,而不是试图减少数千行复杂的代码,这些代码会做很多额外的事情。
对于某些项目,有一些工具可以帮助识别“代码的哪一部分有问题”,例如 [bugpoint
][1] 可以找到 LLVM 中的哪个“pass”导致崩溃的诡计。
如果您有支持此功能的版本控制系统,您可以“平分”代码以得出引入特定错误的版本[至少有时]。然而,我在工作中遇到过这样的情况,我的一些代码“显然破坏了一些东西”,但事实证明,其他一些代码“从很久以前开始就一直被破坏”,因为其他代码没有清除一个指针字段, API手册说应该设置为NULL
,而我的代码正在检查指针以查明它是否指向正确的类型 - 当值为“无论发生什么”时,就会出现严重错误在堆栈的那部分”,因此它不是 NULL 也不是有效的指针。我刚刚添加了使该错误变得明显而不是隐藏自身的代码。
关于c++ - 自动编写 MCVE(重现错误的最小源代码)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30932107/