代码复杂度指标和ifdef

时间:2013-02-25 16:07:28

标签: c++ c c-preprocessor

我想知道如何在面对C / C ++代码中的ifdef时计算标准代码复杂度指标(例如,LOC,McCabe圈复杂度,Halstead度量等)。

如果忽略ifdef,可能会出现语法错误(甚至类型错误),例如:

  1. #ifdef FOO
  2. for(i = 0; i< x; i ++){
  3. #else
  4. for(i = 0; i< y; i ++){
  5. #ENDIF
  6. 的printf(...)
  7. }
  8. 如果忽略第1,3和5行,结果代码将在另一个内部有一个循环,并且缺少'}'(因此语法错误)。

    如果考虑#ifdefs,那么每个变体需要一个结果测量值(在这种情况下,定义FOO时为一个,而未定义FOO时则为另一个)。但是,这种方法在实践中很容易爆炸。

    查看http://manpages.ubuntu.com/manpages/natty/man1/pmccabe.1.html,联机帮助页 报告说:

    解析        pmccabe忽略所有cpp预处理器指令 - 计算        代码外观的复杂性而不是复杂性        在预处理器破坏了代码之后。这一点尤为重要        因为getchar(3)之类的简单东西会扩展为增加的宏        复杂性。

    但是,正如我所说,这种方法可能会导致出现代码错误,这反过来可能会阻碍计算过程或导致错误的值。

    工具如何克服这个问题(如果他们克服了)?

    问候。

3 个答案:

答案 0 :(得分:2)

如果您将该构造重写为

#ifdef FOO
# define LOOPEND x
#else
# define LOOPEND y
#endif

或类似的东西,应该没有问题。

如果您不想这样做,并且复杂性检查程序无法理解预处理程序,则可以在预处理程序的输出上运行它,同时定义FOOFOO undefined,然后获取它产生的值的最大值,以获得实际复杂性的下限。使用GCC,使用gcc -E调用预处理器;其他编译器也有类似的选择。

(当然,如果你有很多这种CPP魔法,那么你就会有很多可能性。但这是你使用预处理器所付出的代价;这同样适用于测试。)

答案 1 :(得分:1)

许多公制计算器不使用完整或符合标准的解析器,而是(可能)执行翻译的前几个阶段,然后查找关键字。

由于他们没有查看您描述的完整语法问题,因此不要阻止它们。但是他们在其他方面确实变得脆弱,事实上我已经看到了在实体生产代码上完全失败的环-2.0。

答案 2 :(得分:0)

我原本以为在一个更大的项目(而不是20行“实验”)中,影响代码的ACTUAL复杂性的#ifdef和类似的数量将相当小 - 你希望这些表达式中的大多数都是孤立的单元,不会过多地影响总体得分。

但是,是的,如果您在#ifdef部分中有一小部分代码#ifdef和复杂性,那么您可能会遇到很大的错误。手动检查代码就能告诉你这一点。