C 使用define强制调用函数

C 使用define强制调用函数,c,c-preprocessor,C,C Preprocessor,假设我有以下代码: void test(void) { #define INIT_DONE //General initialization stuff } void test2(void) { #ifndef INIT_DONE #error "Call function test() first!" #endif // Specific initialization stuff } 然后我主要调用这些函数,如下所示: in

假设我有以下代码:

void test(void) 
{        
    #define INIT_DONE
    //General initialization stuff
}

void test2(void)
{
    #ifndef INIT_DONE
    #error "Call function test() first!"
    #endif
    // Specific initialization stuff
}
然后我主要调用这些函数,如下所示:

int main(void)
{
    test();
    test2();
}
即使我先调用test,然后定义INIT_DONE,我仍然得到:

先调用函数测试

编译器上的错误


那么,我如何才能实现,函数测试必须在任何其他函数之前首先被调用。我可以用一些全局布尔变量或者别的什么来做,但是我希望有一种预处理器的方法来做。有吗?

预处理器在将代码处理到编译器之前运行。它所做的一切都发生在代码运行之前。前置处理器没有函数或变量的概念,它只是将输入复制到输出,并在其间扩展宏。它实际上做了更多的事情,但这并不重要。对于您的代码,预处理器基本上可以看到:

gibberish

    #define INIT_DONE

    // comment

more gibberish

    #ifndef INIT_DONE
    #error "Call function test() first!"
    #endif
    // another comment

even more gibberish
预处理器遍历该过程,首先看到define INIT_DONE,因此它将宏INIT_DONE定义为1;在编译器看到代码之前,INIT_DONE的每个未来外观都将被丢弃的1替换。然后它会看到ifndef INIT_DONE,但是INIT_DONE已经定义好了,所以它跳过了下面的位

关键是,在任何时候,预处理器都不关心执行的是什么。要做您想做的事情,请使用以下方法:

#include <assert.h>

/* only visible in the source code form where test() and test2() are defined */
static int init_done = 0;

void test(void)
{
    init_done = 1;
    /* ... */
}

void test2(void)
{
    assert(init_done);
    /* ... */
}

预处理器在将代码处理给编译器之前运行。它所做的一切都发生在代码运行之前。前置处理器没有函数或变量的概念,它只是将输入复制到输出,并在其间扩展宏。它实际上做了更多的事情,但这并不重要。对于您的代码,预处理器基本上可以看到:

gibberish

    #define INIT_DONE

    // comment

more gibberish

    #ifndef INIT_DONE
    #error "Call function test() first!"
    #endif
    // another comment

even more gibberish
预处理器遍历该过程,首先看到define INIT_DONE,因此它将宏INIT_DONE定义为1;在编译器看到代码之前,INIT_DONE的每个未来外观都将被丢弃的1替换。然后它会看到ifndef INIT_DONE,但是INIT_DONE已经定义好了,所以它跳过了下面的位

关键是,在任何时候,预处理器都不关心执行的是什么。要做您想做的事情,请使用以下方法:

#include <assert.h>

/* only visible in the source code form where test() and test2() are defined */
static int init_done = 0;

void test(void)
{
    init_done = 1;
    /* ... */
}

void test2(void)
{
    assert(init_done);
    /* ... */
}

由于预处理器宏是预编译处理的,因此其名称更不用说运行,因此非常确定它们不会满足您的需要。一个总是被称为测试的全局宏或静态宏浮现在脑海中。由于预处理器宏是预编译处理的,因此它的名称很少运行,所以它们肯定不能满足您的需要。一个总被称为测试中的全局或静态出现在脑海中。感谢您清除一切!我将采用文档化方法,因此已修复。不知怎的,我把这种情况和你在没有A=的情况下通过-DMACRO时发生的事情搞混了。谢谢你清除了一切!我将采用文档化方法,因此已修复。不知怎的,我把这种情况和当你在没有a=的情况下传递-DMACRO给cc时会发生什么混淆了。