C 函数类似于宏大括号或do..while

C 函数类似于宏大括号或do..while,c,macros,C,Macros,可能重复: 你好, 我有以下类似宏的函数,只是想知道跨多行使用时的首选用法是什么。最好使用大括号或执行..while(0)循环 通常我使用do..while(0)表示所有内容。但我看到一些项目,他们只是使用花括号,我不知道哪一个会更好 一会儿 #define DSO_ERROR(msg, res_handle_module, mem_pool, size) do { \ char *dso_error = apr_palloc((apr_pool_t*)mem

可能重复:

你好,

我有以下类似宏的函数,只是想知道跨多行使用时的首选用法是什么。最好使用大括号或执行..while(0)循环

通常我使用do..while(0)表示所有内容。但我看到一些项目,他们只是使用花括号,我不知道哪一个会更好

一会儿

#define DSO_ERROR(msg, res_handle_module, mem_pool, size)   do {        \
        char *dso_error = apr_palloc((apr_pool_t*)mem_pool, size);      \
        apr_dso_error((apr_dso_handle_t*)res_handle_module, (char*)dso_error, (apr_size_t)size); \
        LOG_ERR("%s dso error %s", (char*)msg, dso_error);              \
        goto dso_failure;                                               \
    } while(0); 
花括号

#define DSO_ERROR(msg, res_handle_module, mem_pool, size) {             \
        char *dso_error = apr_palloc((apr_pool_t*)mem_pool, size);      \
        apr_dso_error((apr_dso_handle_t*)res_handle_module, (char*)dso_error, (apr_size_t)size); \
        LOG_ERR("%s dso error %s", (char*)msg, dso_error);              \
        goto dso_failure;                                               \
    }
唯一的区别是分号将预设在do..while循环上,而不是花括号上

非常感谢您的建议,

通常在宏中的(0)时,
do{…}上没有分号


宏之所以有
do{…}while(0)
,是因为这样可以在源代码中使用宏并添加分号,而不需要额外的空语句。我想这主要是出于历史原因,因为在许多情况下,有空语句(即没有任何语句的分号)不会起任何作用。

大括号版本将打破这种用法:

if( foo )
  DSO_ERROR("Foo occured!", my_module, the_pool, 4711);
else
  printf("All is well, there is no foo\n");

这正是
do。。。而(0)
构造。因此,这似乎值得避免。

您将遇到以下代码的问题:

if (one) 
  DSO_ERROR("one", ...);
else
  DSO_ERROR("two", ...);

因此,如果使用不带分号的do-while宏,就可以了。

天哪,这是一段难看的代码。(无意冒犯,我只是非常惊讶)。在
do{…}while(0)
的末尾添加分号首先会破坏使用
do{…}while(0)
的目的。仅大括号版本的缺点是,如果(某些)DSO_错误(…),则无法编写
;else{…}
,因为分号是
if
后面的null语句,
else
是语法错误。对于更正版本的
do{…}while(0)
,如果宏实际上是一个函数,
if
/
else
表示法的工作方式与您所期望的一样。“除了挂起由OP编写的其他问题,“…什么都不做”,do…while(0)版本也会中断,因为它的末尾有一个额外的分号。写入do…while(0)的正确方法是不使用分号。
if (one) 
  DSO_ERROR("one", ...);
else
  DSO_ERROR("two", ...);