【问题标题】:surround a function with a macro用宏包围函数
【发布时间】:2014-01-16 19:28:19
【问题描述】:

我有一个 .c 文件,其中包含一些函数,例如

void foo(void)
{
...doSomeStuff...
}

现在,我想用一些代码包围这个函数,结果是

void foo(void)
{
    ...additional stuff...
    {
        ...doSomeStuff...
    }
    ...do more additional stuff...
}

简而言之,想把整个函数体放到一个“外层”函数中。

我试图让它与一个可以像这样使用的宏一起工作:

MAGIC_MACRO(foo)
{
...doSomeStuff...
}

这样,宏用户(或我)只需要获取 foo 函数的头部并将 void 返回类型替换为 MAGIC_MACRO 内容。 MAGIC_MACRO 应扩展为“附加和更多附加内容”部分。

好的,我认为这很容易。我试图像这些包含 do-while(0) 循环的宏一样实现它。嗯,最大的问题是“更多额外的东西”部分,它必须在旧函数的主体之后。

对此有什么想法吗? 问候,行李

【问题讨论】:

  • 我根本不明白这一点。为什么不简单地从另一个函数调用foo?如果您想“替换” foo,只需更改原始名称的名称(如果您真的喜欢,可以使用宏)。
  • 使用宏来“隐藏”某些东西是一种可怕的滥用。
  • 我已经删除了 c++ 标签,因为它显然是一个 c 文件。如果它实际上是一个 c++ 文件,则添加标签。
  • 你可能是对的。我认为这将是一项简单的任务。但是当我阅读答案时,我想不是。从另一个函数调用 foo() 可能是一个解决方案。好吧,关键是用一些测试代码扩展 foo,在开发过程中提供一些信息。并且无需手动添加此代码。我认为这个宏可以很容易地添加测试代码。

标签: c


【解决方案1】:

我不建议这样做,但您可以让宏创建一个包含进入/退出代码的函数,另一个包含用户提供的代码:

#include <stdio.h>

#define MAGIC_MACRO(f) \
    void f##_inner(void); \
    void f(void) { \
        printf("entry\n"); \
        f##_inner(); \
        printf("exit\n"); \
    } \
    void f##_inner()

MAGIC_MACRO(foo)
{
    printf("foo\n");
}

int main(void) {
    foo();
    return 0;
}

MAGIC_MACRO 的调用将创建foofoo_inner 函数,其中foo 调用foo_innerfoo_inner 包含用户代码,允许将其全部放在宏调用之后。

Live example

【讨论】:

    【解决方案2】:

    你可以在几个宏组合中做到这一点:

    #define BEGIN_INT_FUNCTION(name) \
      int name() {\
      do something...
    
    #define END_INT_FUNCTION \
      do something...
      return 0; \
    }
    

    现在你编写函数代码:

    BEGIN_INT_FUNCTION(name)  // or without argument
    {
      function body...
    }
    END_INT_FUNCTION
    

    你这样称呼它:

    int x = name();
    

    【讨论】:

      【解决方案3】:

      简而言之,就是想把函数的整个主体放在里面 “外部”函数。

      这种宏的语法必须将函数的整个主体作为参数,这不是

      MAGIC_MACRO(foo)
      {
      ...doSomeStuff...
      }
      

      但是

      MAGIC_MACRO(foo,
      {
      ...doSomeStuff...
      })
      

      或许

      MAGIC_MACRO(void foo(void),
      {
      ...doSomeStuff...
      })
      

      这种方法的真正问题是看到有特殊字符、#pragma 和其他可能在正文中找到的东西,它们不能使用宏参数传输。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-06-09
        • 1970-01-01
        • 2018-01-03
        相关资源
        最近更新 更多