【问题标题】:in C is it possible to have a macro with conditonal break statement在 C 中是否可以有一个带有条件中断语句的宏
【发布时间】:2021-04-02 11:50:57
【问题描述】:

以下想法在 C 中是否可行?

我到达失败。 (使用在线c编译器测试)

也许它可以使用 GOTO 解决,但这不是我们所希望的。

只是理论上的,如果我缺少任何其他解决方案,但想法是让状态机更高效一点。

#include <stdio.h>
#include <stdint.h>

uint8_t shouldhavebreaked = 0;
#define BREAK_CONDITIONAL(x,y) do { if(x == y) { shouldhavebreaked = 1; break ;}  } while(0)

int main()
{
    uint8_t swh = 0;

    switch (swh)
    {

    case 0:
 
    /*if state is same, break, otherwise fall-through*/
    BREAK_CONDITIONAL(swh, 0);

    case 1:
        printf("failed \n");
        break;

    }
    printf("changed? %d \n",shouldhavebreaked);
    return 0;
}

【问题讨论】:

  • break 退出宏内部的do 循环,而不是switch。删除宏中的循环。
  • 我建议写if ( swh == 0 ) break;而不是用宏来混淆控制流
  • @M.M 一般来说,我同意,但在某些情况下(例如状态机),您可以使用一组符号宏来创建小型语言

标签: c macros switch-statement break


【解决方案1】:

那些类型的宏没有任何意义(除非你想让代码更难阅读、理解和维护。它也更容易出错)。避免成为瘟疫。它们看起来像函数,其实不是。

如果我从@wildplasser 答案中隐藏了宏,你能猜出这个废话是做什么的吗?

    if(c)
    {
        BREAK_CONDITIONAL(a,b) c = a+b;
    }

【讨论】:

  • 在这种情况下,(因为if() 部分内部有一个中断)它会做同样的事情。正如预期的那样,dangling else 将与最里面的if 相关联。
  • @wildplasser 我想你不明白。
  • 但是为什么您认为省略; 会导致预期的行为吗?在您的情况下,它不会导致语法错误(就像在时髦的 do{}while() 情况下一样)。
  • @wildplasser 你肯定不明白。两者都没有任何意义
  • @P__JsupportswomeninPoland 你读过 yacc/bison 的输出吗?一个更好的问题:你能做得更好/更清洁吗?如果是这样:去做,而不是仅仅批评它。
【解决方案2】:

你可以使用不那么时髦的if(){} else,而不是funky do{}while()


#define BREAK_CONDITIONAL(x,y) if(x == y) { shouldhavebreaked = 1; break; } else

而且在宏中给参数加括号也是一个好习惯:


#define BREAK_CONDITIONAL(x,y) if((x)==(y)) { shouldhavebreaked=1;break;} else

【讨论】:

  • 这个怪物的用法导致BREAK_CONDITIONAL(a,b) c = a+b;是什么语言?永远不要建议这种废话。有史以来最严重的宏观滥用之一。 godbolt.org/z/v3Kroo
  • else 结束宏比不要求; 更糟糕
  • 我接受这个答案,我不使用 else,并且程序正在构建没有 else,所以我很高兴这一刻,我还不明白副作用。如果以某种方式使名称像关键字一样突出,就像一些 typedef.. 这样人们会看到它是一个类似中断的函数
  • 如果你能避开dangling else,没关系。 (goto 变体可能更强大,但我不想在这里引发另一场宗教战争......)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-03
  • 2011-02-18
  • 1970-01-01
相关资源
最近更新 更多