在C代码阻止之前强制执行条件检查

时间:2014-04-09 14:17:14

标签: c c-preprocessor conditional-compilation

短篇小说:我想在某些条件编译的代码块中强制执行运行时条件检查,而不是其他代码块。

长篇故事: 我们的 C 代码库在很大程度上依赖于分析。 我们有许多不同的配置文件,几乎每个模块都有#ifdef个至少5-6个不同的配置文件,包含大段代码。

我们添加了一项新要求 - 对于某些配置文件(假设为<A><B>),只有在满足特定条件时才会运行有条件编译的代码。对于其他配置文件(假设为<C>),这不是必需的。

即,这就是代码现在的样子:

#ifdef <A>
    /* Profiled code… */
#endif /* <A> */

#ifdef <B>
    /* Profiled code… */
#endif /* <B> */

#ifdef <C>
    /* Profiled code… */
#endif /* <C> */

这就是我们需要它的样子:

#ifdef <A>
    if (new_condition)
    {
        /* Profiled code… */
    }
#endif /* <A> */

#ifdef <B>
    if (new_condition)
    {
        /* Profiled code… */
    }
#endif /* <B> */

#ifdef <C>
    /* Profiled code… */
#endif /* <C> */

到目前为止,非常好。

但是,通过上述实现,新要求实际上无法维护。 它不会阻止任何不熟悉添加新配置代码块的要求的人,而不会添加new_condition的检查。

因此,我希望强制我们的工程师在添加<A><B>下分析的新块时检查此情况,但不会针对<C>下的代码进行检查。

理论上,如果#ifdef <A>#ifdef <B>没有直接跟随if (new_condition),那么最佳解决方案可能是失败构建过程的一种方法。

事情是,我不知道这样做。你们有没有人?

3 个答案:

答案 0 :(得分:0)

我有理由相信它不能按照描述完成。您的工程师似乎可以将#ifdef中的所有代码写入#endif,并且您拥有的唯一“钩子”是条件符号和条件。这还不够。一些半随机的想法:

  • 您可以将'条件'转换为函数调用并计算它被调用的频率。
  • 当所有条件都设置为false时,您可以要求某些“空行为”。
  • 您可以创建一些工程师必须在其块内调用的函数来访问某些函数,并在运行时检查如果条件为false则不会调用它。

最终,我认为您最好使用源代码分析工具来分析源代码并报告编码风格违规行为。那将是CppCheck或其中之一:http://en.wikipedia.org/wiki/List_of_tools_for_static_code_analysis

答案 1 :(得分:0)

有点难以回答这个,因为一切都很模糊:)但我建议使用一些包装器,编辑代码的人不允许更改:

typedef void(*stuff_ptr)(void);

inline void do_stuff (stuff_ptr stuff)
{
  #if defined(A) || defined(B)
  if (!new_condition)
  {
    return ;
  }
  #endif

  stuff();
}

#ifdef A
  do_stuff(A_stuff);
#endif

#ifdef B
  do_stuff(B_stuff);
#endif

#ifdef C
  do_stuff(C_stuff);
#endif

这不会无法构建,而是首先防止错误的构建发生。

如果需要,可以将do_stuff()实现为类似函数的宏,但如果可以,请避免使用它。 &#34; new_condition&#34;如果需要,可以作为另一个参数传递。

答案 2 :(得分:0)

维护当前开始宏,结束宏样式块的一个想法可能类似于以下内容:

#include <stdio.h>

#define FOO 1
#define BAZ 1

int condition_a = 1;
int condition_b = 0;

#ifdef FOO
#  define FOO_BEGIN if (condition_a) {
#  define FOO_END }
#else
#  define FOO_BEGIN if (0) {
#  define FOO_END }
#endif

#ifdef BAR
#  define BAR_BEGIN if (condition_b) {
#  define BAR_END }
#else
#  define BAR_BEGIN if (0) {
#  define BAR_END }
#endif

#ifdef BAZ
#  define BAZ_BEGIN if (1) {
#  define BAZ_END }
#else
#  define BAZ_BEGIN if (0) {
#  define BAZ_END }
#endif

int main (int argc, char ** argv)
{
    FOO_BEGIN
        printf("in foo\n");
    FOO_END

    BAR_BEGIN
        printf("in bar\n");
    BAR_END

    BAZ_BEGIN
        printf("in baz\n");
    BAZ_END
}

打印

in foo
in baz

您将不得不更新定义进入和退出块的宏,或者需要在ifdefs中定义某些内容。