是否存在制作“打印消息并继续”宏的正确方法?

时间:2019-07-11 13:12:23

标签: c macros

我希望能够做这样的事情:

while (line = fgets(line, n, input)) {
    if (strlen(line) == 1)
        print_and_continue("Blank line.\n");
    printf("%s\n", line);
}

Ordinarily做到这一点并涵盖所有语法复杂性的方法是采用奇特的do while(0)循环:

#define print_and_die(x) do {printf("%s\n", (x)); exit(1);} while (0)

但是,我不能用continue代替break(或exit(1)),因为它将适用于{{1 }}循环,而不是我想要的循环。当然,我可以像这样定义宏:

do while(0)

并且希望用户不要编写这样的代码:

#define print_and_continue(x) {printf("%s\n", (x)); continue;}

但是我想知道,有没有一种方法可以涵盖所有语法情况?


在评论中,关于该结构的构造是否足够有用以至于有必要避免直接写作的争论不休:

if (something)
   print_and_continue(x);
else {...}

仅是为了说明这一点,如果有很多条件使您想跳过处理数据(或在跳过之前甚至部分处理数据),那么是的,它非常有用。

比较两者的可读性。 后者是重复性的,而且不可读(编辑起来比较棘手)

if (condition) {
   printf("Failure.\n");
   continue;
}

2 个答案:

答案 0 :(得分:1)

您不应该这样做(如评论中所述)。 如果您仍然想要这样做(不应该这样做),则可以这样尝试:

#include <stdio.h>

#define print_and_continue(x) if(printf("%s\n", (x))) continue; else do{} while(0)

int main(int argc, char* argv[]) {
    for(int i=0;i<argc;++i) {
        if(i%2==0)
            print_and_continue("Even arg");
        else
            printf("Uneven arg\n");
        printf("This is printed\n");
    }
}

答案 1 :(得分:1)

if(1){printf("%s\n", (x));continue;}else{}应该可以工作,但是如果在if之后放置这样的宏,则will generate warnings应该在现代编译器(gcc / clang)上使用嵌套if-else。

switch(1){case 1: printf("%s\n", (x))); continue;}应该更具警告性。

如果您希望break拥有相同的功能,并且没有可能出现的嵌套警告,则需要使用statement-expression扩展名:({ printf("%s\n", (x)); continue; /*or break*/ })

如果您的实际用法确实像print_and_continue宏一样简单,那么我认为显式puts(X); continue;比带有隐藏控制流更改的宏更可取。