做{..} while(0)宏替换 [英] do{..}while(0) macro substitutions

查看:52
本文介绍了做{..} while(0)宏替换的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很多时候,在阅读开放软件时,我会遇到以下定义的宏:


#define CALL_FUNCS(x)\

做{\

func1(x); \

func2(x); \

func3(x); \\ b
}而(0);


现在,当然这会有效,但这有什么比这更好:

#define CALL_FUNCS(x)\

{\

func1(x); \

func2(x); \

func3(x); \\ b
}


i无法看到编译器如何优化(a)优于(b)或

任何情况都可以(b)打破(a)不会。任何输入将不胜感激。


tia

A lot of times when reading open software, i come across macros that are
defined as follows:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0);

now, of course this will work but how is this any better than:

#define CALL_FUNCS(x) \
{ \
func1(x); \
func2(x); \
func3(x); \
}

i can''t see how the compiler can optimize (a) any better than (b) or in
any case can (b) break what (a) won''t. Any input will be appreciated.

tia

推荐答案

你好,


Yanaécrit:
Hello,

Yan a écrit :
很多时候,在阅读开放软件时,我遇到的定义如下的宏:

#define CALL_FUNCS (x)\
做{\
func1(x); \
func2(x); \
func3(x); \
} while(0);
你确定有;最后?

因为我认为你使用do {} while(0)的原因是这个; !

你不必把它放在那里,我解释了为什么之后...

现在,当然这会起作用,但这怎么可能比:

#define CALL_FUNCS(x)\
{\\ /
func1(x); \
func2(x); \
func3(x); \
}
我无法看到编译器如何优化(a)任何优于(b)或
任何情况都可以(b)打破什么( a)不会。任何输入都将不胜感激。
A lot of times when reading open software, i come across macros that are
defined as follows:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0); are you sure there is ";" at the end ?
because I thought the reason why you use "do { } while(0)" is this ";" !
you don''t have to put it there, and I explain why after...

now, of course this will work but how is this any better than:

#define CALL_FUNCS(x) \
{ \
func1(x); \
func2(x); \
func3(x); \
}

i can''t see how the compiler can optimize (a) any better than (b) or in
any case can (b) break what (a) won''t. Any input will be appreciated.



您应该看到它在代码中的使用位置,然后您就会理解!

您将在代码中使用找到这个:


....

CALL_FUNCS(12); / *因为这个;而* /

....


所以预处理器将取代CALL_FUNCS(12):

(a)

....

做{\

func1(x); \

func2(x); \

func3(x); \

} while(0); / *< - this";"将以{0}完美结束{/}
....


(b)

。 ...

{\

func1(12); \

func2(12); \

func3(12); \

}; / *< - 太多";" * /

....


也许有另一个原因,但我确定我读了这个解释

某处(也许在这里)。


Alexandre

-

这就是他们应该在这里教给我们的东西 ,他(哈利波特)想,......,

女孩的大脑怎么工作......它比占卜更有用,无论如何

....


哈利波特与凤凰社

JK罗琳


you should see where it''s used in the code, and then you will understand !
in the code you will find this :

....
CALL_FUNCS(12); /* becareful of this ";" */
....

so the preprocessor will replace CALL_FUNCS(12) by :
(a)
....
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0); /* <- this ";" will end do { } while(0) in good way */
....

(b)
....
{ \
func1(12); \
func2(12); \
func3(12); \
}; /* <- too much ";" */
....

Maybe there is another reason, but I''m sure I read this explanation
somewhere (maybe here).

Alexandre
--
"That''s what they should teach us here", he (Harry Potter) thought, ...,
"how''s girls'' brains work ... it''d be more useful than Divination, anyway
...."

Harry Potter and the Order of the Phoenix
J.K. Rowling


Yan< ro ***** @ gmail.com>写道:
Yan <ro*****@gmail.com> writes:
很多时候,在阅读开放软件时,我遇到的宏定义如下:

#define CALL_FUNCS(x )\
做{\
func1(x); \
func2(x); \
func3(x); \
} while(0);
A lot of times when reading open software, i come across macros that
are defined as follows:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0);




阅读常见问题。

-

Ben Pfaff

电子邮件: bl*@cs.stanford.edu

web : http://benpfaff.org


Yan写道:
很多时候,在阅读开放软件时,我遇到的定义如下的宏:

#define FALL_FUNCS(x)\\做{\
func1(x); \
func2(x); \
func3(x); \
} while(0);
现在,当然这会有效,但这有什么用呢:

#define CALL_FUNCS(x)\
{\
func1(x) ; \
func2(x); \
func3(x); \
}
我无法看到编译器如何优化(a)任何优于(b)或
任何情况都可以(b)打破什么( a)不会。任何输入将不胜感激。
A lot of times when reading open software, i come across macros that are
defined as follows:

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0); now, of course this will work but how is this any better than:

#define CALL_FUNCS(x) \
{ \
func1(x); \
func2(x); \
func3(x); \
}

i can''t see how the compiler can optimize (a) any better than (b) or in
any case can (b) break what (a) won''t. Any input will be appreciated.




这不是关于优化。


使用''do / while的整个想法''版本是制作一个宏将

扩展为常规语句,而不是复合语句。这是为了在所有情况下使用普通函数的

使用函数式宏来完成




考虑以下代码草图


if(< condition>)

foo(a);

else

bar(a);


其中''foo''和''bar''是普通函数。现在想象一下,你想用一个具有上述性质的宏取代函数''foo''


if(< condition>)

CALL_FUNCS(a);

else

bar(a);


现在,如果你的宏是按照第二种方法定义的

(只是''{''和''}'')代码将不再编译,因为''true''
''i'的
分支现在由复合语句表示。当你在这个复合语句之后输入一个'';''时,你完成了整个''if''

语句,从而孤立了''else''分支(因此编译错误)。


纠正这个问题的一种方法是记住在

宏调用之后不要放'';'' ;


if(< condition>)

CALL_FUNCS(a)

else

bar (a);


这将按预期编译和工作,但这不统一。

更优雅的解决方案是确保宏扩展为常规的

语句,而不是复合语句。实现这一目标的一种方法是定义

宏如下


#define CALL_FUNCS(x)\

do { \

func1(x); \

func2(x); \

func3(x); \\ /

}而(0)


现在这段代码


if(< condition>)

CALL_FUNCS(a);

else

bar(a);


将无需任何编译问题。


但请注意我的定义

的''CALL_FUNCS''与你邮件中的第一个版本之间的小而重要的区别。我没有把'/ b $ b'';''放在''}之后(0)''。在该定义的末尾加上'';''

将立即击败使用''do / while''的整个点,并使得

该宏几乎相当多相当于复合语句版本。


我不知道为什么你在原始的

消息中引用的代码的作者把这个'' ;'''''while(0)''。在这种形式下,两种变体都相当于
。使用''do / while''版本背后的整个想法不是为了b / b $ b包括这个最后的'';''进入宏(因为我解释的原因

以上)。


-

祝你好运,

Andrey Tarasevich



It is not about optimization.

The whole idea of using ''do/while'' version is to make a macro which will
expand into a regular statement, not into a compound statement. This is
done in order to make the use of function-style macros uniform with the
use of ordinary functions in all contexts.

Consider the following code sketch

if (<condition>)
foo(a);
else
bar(a);

where ''foo'' and ''bar'' are ordinary functions. Now imagine that you''d
like to replace function ''foo'' with a macro of the above nature

if (<condition>)
CALL_FUNCS(a);
else
bar(a);

Now, if your macro is defined in accordance with the second approach
(just ''{'' and ''}'') the code will no longer compile, because the ''true''
branch of ''i'' is now represented by a compound statement. And when you
put a '';'' after this compound statement, you finished the whole ''if''
statement, thus orphaning the ''else'' branch (hence the compilation error).

One way to correct this problem is to remember not to put '';'' after
macro "invocations"

if (<condition>)
CALL_FUNCS(a)
else
bar(a);

This will compile and work as expected, but this is not uniform. The
more elegant solution is to make sure that macro expand into a regular
statement, not into a compound one. One way to achieve that is to define
the macro as follows

#define CALL_FUNCS(x) \
do { \
func1(x); \
func2(x); \
func3(x); \
} while (0)

Now this code

if (<condition>)
CALL_FUNCS(a);
else
bar(a);

will compile without any problems.

However, note the small but important difference between my definition
of ''CALL_FUNCS'' and the first version in your message. I didn''t put a
'';'' after ''} while (0)''. Putting a '';'' at the end of that definition
would immediately defeat the entire point of using ''do/while'' and make
that macro pretty much equivalent to the compound-statement version.

I don''t know why the author of the code you quoted in your original
message put this '';'' after ''while (0)''. In this form both variants are
equivalent. The whole idea behind using ''do/while'' version is not to
include this final '';'' into the macro (for the reasons that I explained
above).

--
Best regards,
Andrey Tarasevich


这篇关于做{..} while(0)宏替换的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆