【发布时间】:2015-08-08 07:07:20
【问题描述】:
所以...我有宏,它具有“SET”功能并且应该模仿一个函数,它会返回 void。我可以使用 do {...} while(0) 构造来实现此行为,但它是否合法,如果是这样,是否实现定义的行为将某些东西强制转换为 void 来实现此行为? (根据不同版本的 C 标准的话,对我来说最重要的是:C89 仍然)
更具体: 以下函数/宏的行为是否相似(包括合法并在用作右值时引发编译时错误)?
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;
}
【问题讨论】:
-
为什么不能测试呢?或者你为什么不在每个示例中扩展宏,看看它是否有意义?
-
你为什么使用
do {} while(0)这样的构造。这意味着什么! -
@SergioFormiggini 这个结构是 AFAIK 通用的,用于将多个指令封装在一个宏中,但在末尾使用分号保留调用上下文。 “do”将允许在 IF 子句中执行(多条指令)宏,例如“if(...) macro(x,y);”在我的上下文中,它将阻止宏可以合法地用作左值。
-
@Lundin 对于任何常见情况,您都是完全正确的。
do while(0)是大括号的冗余,通常使用它。我问这个问题找到更好的解决方案。但是根据昨天 Armali 的回答,有一种情况是这种结构更可取。 -
@MarkA。不是真的,这个答案并不是那么准确。你应该去看看赋值运算符。在 6.5.16.1 中列出了允许分配的各种情况。它们都不允许正确的操作数是 void 类型,就这么简单。因此,在所有这些情况下,您都会遇到同样多的编译器错误。