【问题标题】:Using if else in c macros在 c 宏中使用 if else
【发布时间】:2017-09-17 16:04:53
【问题描述】:

我正在尝试定义以下宏:

#define UTF8_2B(c) if((0xc0 & c) == 0xc0){return 1;}

但我遇到了错误:

expected expression before ‘if’

宏是这样调用的:

int i = UTF8_2B(c);

其中 c 是从文件中读取的无符号字符。

为什么会这样?不能在宏中使用 if else 语句吗? 另外,我读到在宏中使用分号不是一个好主意,但我不明白为什么。 我是 c 新手,所以答案越全面越好。

【问题讨论】:

  • 如何使用宏? (而且,也许更重要的是:你想实现什么?)
  • 显示你调用这个宏的上下文
  • 宏做文本替换;你不能直接写variable = if (condition) …,所以你也不能使用宏。您也缺少 else 值。而return 在上下文中完全不合适。请记住:宏是文本替换。预处理后,代码必须是有效的C。
  • 不仅如此,连逻辑都错了。 else 的情况应该怎么办?

标签: c macros


【解决方案1】:

C(和 C++)预处理器宏本质上是带有参数替换的“复制粘贴”。所以你的代码变成了:

int i = if((0xc0 & c) == 0xc0){return 1;}

这是无效的语法。

【讨论】:

    【解决方案2】:

    您正在将宏的结果分配给一个变量。你不能用当前宏来做到这一点(return 从当前函数返回,并且不返回要分配给i 的东西:所以不是你想要的)。

    如果您使用的是gcc,您可以使用-E 命令行查看您的预处理代码。

    所以您可以在宏中使用if,但不能在像函数一样使用的宏中使用,因为它们应该返回一个值。

    此外:

    • 如果c 是一个复杂的表达式,运算符优先级可能会使宏生成错误代码
    • 宏应提供一种要求分号的方法,因此 IDE 和人类读者将其视为正常功能

    我建议改用一个简单的测试(如果为真,则为 1,否则为 0),它符合“需要分号”标准,并且可以安全地与复杂的 c 表达式一起使用:

    #define UTF8_2B(c) ((0xc0 & (c)) == 0xc0)
    

    【讨论】:

      【解决方案3】:

      为此目的而存在三元运算符。假设你想要 1 为真,0 为假,正确的宏是:

       #define UTF8_2B(c) (((c) & 0xC0) == 0xC0 ? 1 : 0)
      

      现在您可以分配结果。在宏中使用return 将从封闭函数中返回,而不是从宏中返回,而且几乎总是一个坏主意。

      【讨论】:

      • 错字:C0 -> 0xC0,三元运算符也是多余的:比较已经计算为01
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-12-26
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多