2012-12-07 29 views
6

可能重复:
Do-While and if-else statements in C/C++ macros功能类似宏花括号或do..while

gcc (GCC) 4.7.2 
c89 

你好,

我有以下函数宏,只是想知道在多条线路上使用时的首选用法是什么。使用花括号或do..while(0)循环更好。

通常情况下,我使用do..while(0)来处理所有事情。但是我看过一些项目,他们只是使用花括号,我不确定哪一个会更好。

do..while

#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循环,而不是在大括号来预设。

非常感谢您的任何建议,

+1

我的天啊,这是难看的代码。 (没有任何意图,我只是很惊讶)。 – rubenvb

+3

将分号添加到'do {...}的末尾,while(0)'摆脱了首先使用'do {...} while(0)'的目的。只有花括号的版本的缺点是你不能写'if(something)DSO_ERROR(...); else {...}“,因为分号在'if'后面是空语句,'else'是语法错误。使用'do {...} while(0)'的修正版本时,如果宏实际上是一个函数,那么if'/'else'表示法就像你所期望的那样工作。 –

回答

7

的花括号版本将打破用法是这样的:

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

这是非常原因do ... while(0)结构。所以这似乎值得避免。

+2

由OP编写的,do ... while(0)版本也会因为它在末尾有一个额外的分号而中断。编写do ... while(0)的正确方法是不带分号的。 –

2

通常你做对宏的do { ... } while (0)分号。

你有这个宏的do { ... } while (0)的原因是,那么你可以在源代码中使用宏,并添加一个分号而不需要额外的空语句。我猜这主要是出于历史原因,因为在很多情况下,空语句(即没有任何语句的分号)不会做任何事情。

+5

“......什么都不做”除了悬挂其他问题 –

4

你有这个代码的问题:

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

所以如果你使用DO-而微距无分号,你就可以了。