我想知道如何在面对C / C ++代码中的ifdef时计算标准代码复杂度指标(例如,LOC,McCabe圈复杂度,Halstead度量等)。
如果忽略ifdef,可能会出现语法错误(甚至类型错误),例如:
如果忽略第1,3和5行,结果代码将在另一个内部有一个循环,并且缺少'}'(因此语法错误)。
如果考虑#ifdefs,那么每个变体需要一个结果测量值(在这种情况下,定义FOO时为一个,而未定义FOO时则为另一个)。但是,这种方法在实践中很容易爆炸。
查看http://manpages.ubuntu.com/manpages/natty/man1/pmccabe.1.html,联机帮助页 报告说:
解析 pmccabe忽略所有cpp预处理器指令 - 计算 代码外观的复杂性而不是复杂性 在预处理器破坏了代码之后。这一点尤为重要 因为getchar(3)之类的简单东西会扩展为增加的宏 复杂性。
但是,正如我所说,这种方法可能会导致出现代码错误,这反过来可能会阻碍计算过程或导致错误的值。
工具如何克服这个问题(如果他们克服了)?
问候。
答案 0 :(得分:2)
如果您将该构造重写为
#ifdef FOO
# define LOOPEND x
#else
# define LOOPEND y
#endif
或类似的东西,应该没有问题。
如果您不想这样做,并且复杂性检查程序无法理解预处理程序,则可以在预处理程序的输出上运行它,同时定义FOO
和FOO
undefined,然后获取它产生的值的最大值,以获得实际复杂性的下限。使用GCC,使用gcc -E
调用预处理器;其他编译器也有类似的选择。
(当然,如果你有很多这种CPP魔法,那么你就会有很多可能性。但这是你使用预处理器所付出的代价;这同样适用于测试。)
答案 1 :(得分:1)
许多公制计算器不使用完整或符合标准的解析器,而是(可能)执行翻译的前几个阶段,然后查找关键字。
由于他们没有查看您描述的完整语法问题,因此不要阻止它们。但是他们在其他方面确实变得脆弱,事实上我已经看到了在实体生产代码上完全失败的环-2.0。
答案 2 :(得分:0)
我原本以为在一个更大的项目(而不是20行“实验”)中,影响代码的ACTUAL复杂性的#ifdef
和类似的数量将相当小 - 你希望这些表达式中的大多数都是孤立的单元,不会过多地影响总体得分。
但是,是的,如果您在#ifdef
部分中有一小部分代码#ifdef
和复杂性,那么您可能会遇到很大的错误。手动检查代码就能告诉你这一点。