我们怀疑我们的代码中有这样的东西,
所以也许#ifdef
没有 the#endif
或者没有命名空间 foo {
,}
有什么策略可以在包含数十万个文件的代码库中定位这样的东西,有没有办法使用正则表达式?
编辑 - 忘了提(这是真正邪恶的部分)在这段代码中生成了我们所说的统一文件,它们将每个 cpp 文件拉到一个大的超级 cpp 文件中。因此编译器可能不会报告丢失的大括号或不匹配的 else/ifs,因为它们很容易运行到接下来的几亿行代码中......
我们怀疑我们的代码中有这样的东西,
所以也许#ifdef
没有 the#endif
或者没有命名空间 foo {
,}
有什么策略可以在包含数十万个文件的代码库中定位这样的东西,有没有办法使用正则表达式?
编辑 - 忘了提(这是真正邪恶的部分)在这段代码中生成了我们所说的统一文件,它们将每个 cpp 文件拉到一个大的超级 cpp 文件中。因此编译器可能不会报告丢失的大括号或不匹配的 else/ifs,因为它们很容易运行到接下来的几亿行代码中......
如何在庞大的代码库中找到悬空的命名空间或预处理器指令
在 Visual Studio 中按下Ctrl+]
将导致光标跳转到匹配的大括号或 endif 语句。当你找到一个光标不能跳转的大括号时,它是“悬空的”。另外,您可以折叠部分代码,这可以帮助您找到不匹配的大括号。
我还建议阅读实际的编译器输出而不是错误列表。
拥有数十万个文件
在第一个错误处终止编译,调查导致错误的文件,修复错误,再次尝试编译。使用“编译”而不是“构建解决方案”一次编译一个文件。“要求”编译器生成插入包含文件的输出列表(VS2008 cl.exe 中的 /E 或 /P 开关),然后调查生成的文件。
如果这也不起作用,您将不得不花一些时间编写一个用 python/perl 编写的小型解析器 - 用于检查匹配大括号的解析器。
正则表达式无法真正找到匹配的大括号,特别是如果它们是嵌套的。
我认为最好的方法是确保所有代码都正确缩进,然后很容易看到什么时候丢失了。
除此之外,它是体力劳动匹配的开始和结束。希望它只需要很少做。另请注意,大多数面向编码的现代文本编辑器都非常擅长匹配大括号和括号等内容。
编译器和预处理器会抱怨不匹配的#if / #endif
对或不匹配的大括号。找到编译器抱怨的第一个文件并手动“捏造”它,直到它编译为止。
(不,标准正则表达式不能匹配嵌套到任意深度的对。)
两步流程:
请注意,使用智能编译器,它甚至可以使用统一构建。
与 Clang 一起使用-Wscope
时,如果作用域(例如命名空间)从文件(例如标头)开始,但没有结束,您会收到警告。可以在邮件列表中找到引入此补丁的补丁。它将在 3.1 版本中提供。
我认为 Clang 中没有对应的预处理器指令。
答案是不要(有效地)将 100000 个文件粘贴到一个文件中,以便在每个文件编译时,编译器会在结束时立即知道存在不匹配的内容。然后使用生成的错误消息和正常的代码检查来查找丢失的指令或大括号应该是微不足道的。
这无论如何都不是一个完整的答案,但我确实发现使用这个正则表达式很有帮助:
// *\#if|\#el|\#en
它搜索 // 后跟任意数量的空格(包括无),然后是 #if、#el 或 #en(以排除抛出所有 pragma 等的可能性 - 这绝对可以改进。
幸运的是,我只需要在打开的文档中进行搜索,这有数百个,但可能会更糟。希望这对将来的某人有所帮助,这太可怕了!
这可能与您的问题无关,但是在 #if/#else/#endif 块中构建一些头文件时出现“意外的 #else”错误。
我发现如果我将问题模块设置为不使用预编译头文件,问题就会消失。与“#pragma hdrstop”有关的内容不应包含在#if/#endif 中。