如何在函数体中使用外部宏?

时间:2013-11-10 23:14:52

标签: c macros

我正在编写一个应该有两个版本的函数:调试版和非调试版。使用这两个函数中的哪一个应该由调用者决定。

我想要这样的事情:

caller.c

// comment out the following line when not necessary anymore
#define MY_FUNC_DEBUG

#include "my_func.h"

// some code that calls my_func()

my_func.h

void my_func(void);

my_func.c

void my_func()
{
    // lots of code

#ifdef MY_FUNC_DEBUG
    // debug code
#endif

    // more code
}

这显然不起作用,因为my_func.c是与caller.c分开编译的,因此无法知道它定义的宏。

如何轻松完成这项工作?我不想分别编写my_func的两个版本,因为它们共享大部分代码。

2 个答案:

答案 0 :(得分:1)

假设您正在使用gcc,可以通过在两个文件中通过-D选项在编译时定义宏来轻松解决此问题。

在您的示例中,您可以在需要激活调试代码时使用-D MY_FUNC_DEBUG编译这两个文件,否则无需编译。无需在caller.c中定义MY_FUNC_DEBUG

答案 1 :(得分:0)

使my_func()中的调试代码在运行时可切换。

my_func.h

#ifndef MY_FUNC_H_INCLUDED
#define MY_FUNC_H_INCLUDED

extern int my_func_debug(int level);
extern void my_func(void);

#endif

my_func.c

#include "my_func.h"

static int debug = 0;

int my_func_debug(int level)
{
    int rv = debug;
    debug = level;
    return rv;
}

void my_func(void)
{
    ...
#ifdef MY_FUNC_DEBUG
    if (debug)
        ...debug...
#endif
    ...
}

caller.c

void consumer(void)
{
    int old = my_func_debug(9);
    my_func();
    my_func_debug(old);
}

讨论

大纲代码意味着您可以拥有my_func.c的源代码的一个副本,但可以使用包含的调试进行编译,也可以将其排除。使用者代码(caller.c)可以请求它想要的调试级别,但这是否有用取决于是否使用调试编译了my_func.o(Windows上为my_func.obj)的副本。你得到一个源文件;您可以选择使用caller.o在程序中包含目标文件的哪个变体。在运行时,您可以请求调试。

请注意my_func_debug()是无条件定义的;如果my_func.c代码未使用-DMY_FUNC_DEBUG进行编译,它就不会做任何非常有用的事情。