假设我有以下代码:
void test(void)
{
#define INIT_DONE
//General initialization stuff
}
void test2(void)
{
#ifndef INIT_DONE
#error "Call function test() first!"
#endif
// Specific initialization stuff
}
然后在main()
中我将这些函数称为如下:
int main(void)
{
test();
test2();
}
即使我先拨打test()
,然后#define INIT_DONE
我仍然会:
"首先调用函数test()!"
编译器出错。
那么,我怎样才能实现,在任何其他函数之前必须首先调用函数test()
。我可以使用一些全局布尔变量或其他东西,但我希望有一个预处理器方法来做到这一点。有吗?
答案 0 :(得分:4)
预处理器在将代码处理到编译器之前运行。它所做的一切都在你的代码运行之前发生。预处理器没有函数或变量的概念,它只是将输入复制到输出并在其间扩展宏(它实际上做了一些更多的东西,但这并不重要)。对于您的代码,预处理器基本上可以看到:
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);
/* ... */
}
由于预处理程序在程序运行之前运行,因此通常无法在预处理程序中执行此操作。您也可以退出这些检查,并强调初始化需要在您的文档中完成。另一种方法是根本不需要程序员初始化,这取决于具体情况:
static int init_done = 0;
/* same initialization function as before */
void test(void)
{
init_done = 1;
/* ... */
}
void test2(void)
{
if (!init_done)
test();
/* ... */
}