处理可能包含未定义行为的项目

时间:2016-01-29 06:37:11

标签: c++ undefined-behavior

我想建议如何处理这种情况。 想象一下,我有一个很好的C ++项目。

我怀疑这段代码中可能有一些UB(因为在同一作者写的不同项目中我找到了UB)。

现在,我需要为这个项目添加新功能。 我害怕因为:

  • 如果我使用新编译器重新编译,如果代码中已经是UB,则会增加UB发生的风险。 (例如,新的编译器可能不适合使用旧编译器的UB)。

通过眼睛检查(在我添加新功能之前)消除这个大型项目中的所有UB是否现实???

如果没有,那么我至少应该使用相同版本的编译器编译吧? (如果有UB,减少出现问题的机会)。

Project在Visual Studio中完成,所以我不知道是否有目标文件,在这种情况下,我可以保留目标文件相同,只修改我需要添加内容的文件中的部分 - 从而再次将风险降至最低UB。

在这种情况下的行动方针是什么?我认为这可能是非常常见的情况。

我喜欢建议我在添加新代码之前使用新编译器测试项目,但即便如此 - 我们知道测试可能不会显示UB,不是吗?

3 个答案:

答案 0 :(得分:4)

按顺序,我会:

  1. 使用-Wall/W4为您编辑Windows用户)并修复错误。
  2. 如果没有,则编写测试。
  3. 使用valgrind等工具来检测问题并进行修复。
  4. 在使用时研究同步原语,并在可能的情况下使用现代范例。
  5. 记录代码并遵守样式指南。
  6. 我不会试图通过保持对象文件来避免问题。这是一个噩梦般的维护问题。

答案 1 :(得分:3)

未定义的行为=错误

无法证明项目没有错误。即使是最优秀的程序员也会创建错误。即使是最好的代码审查也无法消除项目中的所有错误。不,通过代码检查或任何其他方式消除某个规模的项目中的所有UB是不现实的。您最好的选择是查看代码并尽可能多地删除。

  • 改变你对UB的看法(错误):如果你在重新设计工作中遇到错误,这是件好事!您最有可能移除一个UB。

  • 不要因为害怕UB而保留旧编译器。使用最新和最好的编译器重新编译项目。编译器也可能有bug。较新的编译器将生成更好,更健壮的代码。较新的编译器将产生更好的警告。尽可能使用所有警告-Wall

  • 消除编译器产生的所有警告。每一个警告都是有原因的,它突出了一个问题。假阳性的可能性"现在很朦胧。对于MSVC来说,情况确实如此(我不是在谈论像VC 2005之前那样真正的旧编译器)

  • 使用静态代码检查器(Cppcheck)。它可以指出代码的常见问题。

  • 使用custom rule set代码检查。它将帮助您将代码提升到某种标准。

  • 如果可能的话,只是为了获得这些编译器的警告,用另一个编译器(GCC,Clang)编译项目。

  • 不要链接旧的目标文件。这会产生比你认为避免的问题更多的问题

答案 2 :(得分:2)

正如其他人所说:首先,尝试找出错误,而不是隐藏它们。

  1. 第一个也是最简单的方法是将警告级别设置为/W4(您可以尝试Wall,但由于会产生大量噪音(例如来自标准的标题文件),因此通常只有在您知道代码的某个部分出错时才提供帮助)
  2. 使用静态分析器 - 您可以从内置Code Analysis工具开始,然后选择外部工具(对于非平凡的项目来说,这些工具通常要设置得更加困难)。
  3. 写下大量的测试,并确保你正在处理边缘情况 - 这是UB通常潜伏的地方。
  4. 如果可能,尝试在clang下编译项目(或部分项目)并激活不同的清洁剂(特别是UndefinedBehaviorSanitizer),这将进一步检测代码以检查UB(仅在您有用时)有测试来锻炼UB虽然)
  5. 在不同的优化级别和标志组合中测试您的代码(在VS中,尤其是_ITERATOR_DEBUG_LEVEL可以帮助您找到越界错误)
  6. 我说任何非平凡的代码库都可能包含未定义的行为。那个特定的程序员有什么特别之处?如果他/她倾向于使用特殊类型的UB,那么您可以专注于此。