【问题标题】:Macro issue, with multiple statements宏问题,有多个语句
【发布时间】:2012-01-20 16:21:25
【问题描述】:
#define RUN_SOME_STUFF(...) {                                        \
            int x = 0;                                               \
            printf("[INFO] Do some stuff here ... %d\n", ++x);       \
            {__VA_ARGS__}                                            \
            printf("[INFO] end some stuff here\n");                  \
        }

我是如何使用它的:

...
RUN_SOME_STUFF(
{
    // middle:
    int y;
    y = 100;
    printf("Middle\n"); 
});
...

现在,我知道这被认为是一个(非常)丑陋的宏,但这是我寻求帮助的主要原因。

这样做的第一个问题是,如果出现任何类型的错误,编译器会将宏的最后一行显示为不正确的行。打印内容只是简化问题的示例(在两个代码 sn-ps 中),因此可能有 20 行复杂的嵌套代码,在这种情况下非常烦人。

第二个是__LINE__的解析方式同样不正确

&我相信还有更多...

1. 有什么办法可以纠正以上问题,使线路得到正确解决? (可能是某种编译器选项?,我正在使用 VS2008/2010)

2. 如果没有办法用宏以“可爱”的方式制作它,我还有其他选择吗?简单地说,我只想“围绕”(之前和之后)运行一些其他代码。

编辑:我会经常使用这个宏,总是有不同的“中间”内容,所以我不能每次都写一个内联函数。

【问题讨论】:

  • 您有什么理由要为此使用宏吗?如果您只想在另一个输出之前和之后打印内容,您应该使用 sprintf 将中间内容放在缓冲区中,然后调用一个函数(而不是宏)传递已经格式化的缓冲区,然后您可以使用 printf 调用输出该缓冲区。
  • 正如我在问题中所说,printf-s 只是过度简化,我需要更复杂的代码来代替 printf-s。
  • 你可以改为内联函数。
  • 添加了对我的问题的编辑作为对此评论的回答。
  • 那些不是问题——它们是功能。这就是宏扩展被定义为在 C 中工作的方式。特别是,作为宏扩展过程的一部分,宏参数中的所有换行符都会被删除,因此整个事情最终会变成一行。

标签: c visual-studio compiler-construction macros


【解决方案1】:

您可以将宏分成两部分。不漂亮,但是当宏配对时它可以工作。 RUN_BEGIN;RUN_END; 下面都写了,所以它们需要一个分号。

#define RUN_BEGIN \
    do { \
        int x = 0;   \
        printf("[INFO] Do some stuff here ... %d\n", ++x);  \
        {  \
            (void)0

#define RUN_END  \
        } \
        printf("[INFO] end some stuff here: %d\n",x ); \
    } while (0)

【讨论】:

  • 嗯,是的,它好一点(正如之前评论的那样),因为至少“中间”语句的行被正确解析了。
  • 仍然注意这里的“int x = 0”可能没有达到预期的效果。如果它打算记录调用代码的时间,我至少会在之前添加一个“静态”。这也适用于以前的帖子。
  • 在这个宏的真实版本中,我使用静态变量(尤其是因为它是多线程的)。但我在这里简化了。
【解决方案2】:

使用function pointers 可能会更好。我还没有编译这个,但类似:

void runSomeStuff(void (*stuff)(void))
{
    int x = 0;                                                   
    printf("[INFO] Do some stuff here ... %d\n", ++x);       
    (*stuff)();                                           
    printf("[INFO] end some stuff here\n");    
}

【讨论】:

  • 正如后面的编辑状态,我需要多次执行此操作,有时针对单个语句,有时针对 10 行代码。总是写一个新函数是一个非常混乱的解决方案。
  • 有没有可能比使用#define 更混乱?
  • @lerosQ,大多数人认为功能太少比太多更麻烦。
  • “大多数人”是对的,但在这种情况下,它会有很大帮助(如果存在解决方案......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-14
  • 2015-08-03
  • 1970-01-01
相关资源
最近更新 更多