宏可以通过转换为 void 来模拟 void 返回函数吗?

Can macros mimic void returning functions by casting to void?

所以...我有宏,它具有 "SET" 功能并且应该模仿一个函数,这将 return 无效。我可以使用 do {...} while(0) 构造来实现此行为,但它是否合法,如果是的话,它是否是实现定义的行为以将某些内容强制转换为 void 来实现此行为? (根据不同版本的C标准的说法,对我来说最重要的:C89仍然)

更具体: 以下 functions/macros 的行为是否相似(包括合法且用作右值时会引发编译时错误)?

  void setFunction(int * const pVar, const int intvalue) /* as function */ 
  {
        *pVar = intvalue;
        return;
  }

  #define SET_MACRO_DW(pVar,intvalue) \
          do { \
               *(pVar) = (intvalue); \
             } while (0)

  #define SET_MACRO_C2V(pVar,intvalue) \
          ((void) (*(pVar) = (intvalue)))


  void test()
  {
       int target;
       int value = 17;
       int retDummy;

       setFunction(&target, value); /* ok */
       SET_MACRO_DW(&target, value); /* ok */
       SET_MACRO_C2V(&target, value); /* ok? */

       retDummy = setFunction(&target, value); /* CT error/warning */
       retDummy = SET_MACRO_DW(&target, value); /* CT syntax error */
       retDummy = SET_MACRO_C2V(&target, value); /* ??? */
       return;

  }

Are the following functions/macros are behaving similar (including being legal and provoking compile time errors when used as rvalue)?

它们在正确使用时(即不在赋值中)表现相似,并且可能但不一定在用作右值时表现相似(见下文)。

它们当然只有在正确使用时才合法。

关于编译时错误,从 C89 到 C11 的标准在 环境/概念模型/翻译环境/诊断 部分与 C89 中的措辞非常相似(粗体文本在 C99 中添加):

A conforming implementation shall produce at least one diagnostic message (identified in an implementation-defined manner) for every translation unit that contains a violation of any syntax rule or constraint, even if the behavior is also explicitly specified as undefined or implementation-defined. Diagnostic messages need not be produced in other circumstances.

现在,当使用您的 function/macros 作为右值时,我们有两种情况。

  1. SET_MACRO_DW()
    它扩展到的 do while 语句在赋值表达式中显然违反了语法规则 assignment-expression,因此必须生成诊断消息。

  2. setFunction()SET_MACRO_C2V()
    这些是 void 表达式。作为右值,它们不违反任何语法规则,所以问题是是否违反了任何约束。 语言/转换/其他操作数/void部分的以下措辞从 C89 到 C11 没有改变。

    The (nonexistent) value of a void expression (an expression that has type void) shall not be used in any way, and implicit or explicit conversions (except to void) shall not be applied to such an expression.

    此外,标准的措辞与

    非常相似

    In this Standard, "shall" is to be interpreted as a requirement on an implementation or on a program; conversely, "shall not" is to be interpreted as a prohibition.

    If a "shall" or "shall not" requirement that appears outside of a constraint is violated, the behavior is undefined.

    现在,我无法确定上述对空表达式的要求是否构成约束,所以我问了 结论是以上不是标准意义上的约束,因此在用作右值时不能保证错误消息(尽管每个理智的编译器都应该产生一个错误消息)并且 使用导致 未定义的行为 。但是语言/表达式/赋值运算符/简单赋值:

    部分仍然存在约束

    One of the following shall hold: …

    其中 none 成立,因此我们违反了约束,即使行为未明确定义,也会保证出现错误消息。

因此,SET_MACRO_DW() 是您提供的三个结构中最简单、最简单的结构。