Do{...} Use of while (0)

Source: Internet
Author: User

Welcome reprint, Reproduced please specify the original address: http://blog.csdn.net/majianfei1023/article/details/45246865


0. Guidance
The first time I saw do{...} while (0) is when learning libevent, see there are many similar
#define Tt_uri (Want) do {char *ret = Evhttp_uri_join (URI, url_tmp, sizeof (URL_TMP)); Tt_want (ret! = NULL); Tt_want (ret = = U RL_TMP); if (strcmp (ret,want)! = 0) Tt_fail (("\"%s\ "! = \"%s\ "", Ret,want));} while (0)


I was particularly puzzled, do{...} while () is not a loop, similar to for,while syntax, but in reality development, with for and while more, do{...} while () is less, is a relatively less commonly used syntax.
But here, the code looks like a loop, do. While the surface is meaningless here, why use it so much? Especially puzzled Google, suddenly, the original do{...} while () There are such magical things, it seems that they are still far.


Generally speaking, do{...} while (0) there are two ways to use it.


Define a macro to implement a local scope.

1. When you do C language topics, a must-have exam is #define的算术运算.
For example, I write a simple # define
#define FUNC (x) x*3+4...int result = 2 * FUNC (3);

How much does the result output? 26? Wrong!
This is a C language novice will make a mistake, at least when I went to college, the first time I saw this, I did wrong.
To know the answer to this question is how much, you must first know the role of # define.
1). #define M (A+B) Its role is to specify an identifier M instead of an expression (a+b). When writing the source program, all (A+B) can be replaced by M, while the source program is compiled, the preprocessor will be a macro substitution, that is, the (a+b) expression to replace all the macro name M, and then compile.
2). The C language allows macros with parameters. The parameters in the macro definition are called formal parameters, and the parameters in the macro call are called actual parameters. For a macro with parameters, in the call, not only the macro expansion, but also with the actual parameter to replace the parameter. (The above two sentences from the Baidu Encyclopedia)

That's #define是在预处理的时候进行直接替换! (This sentence is the focus of this section)
For example, the expansion above is.
int result = 2 * x * 3 + 4
X is replaced with argument 3:
int result = 2 * 3 * 3 + 4 = 22 instead of 26.


Some people may say, these I know, this with do{...} while (0) what is the relationship.

In fact, I'm just trying to tell you that #define使用的时候要特别小心, especially in # define a very complicated logic.

Let's give an example of a simple # define:

void print () {cout<< "Print:" <<ENDL;} void Send () {cout << "send:" <<ENDL;} #define LOG print (), send (), int main () {if (false) Logcout << "Hello World" <<endl;system ("pause"); return 0;}

What does this code output? In theory, if (false) the code inside will not be executed, that is, log will not be executed, so only "Hello World" should be printed.

But in fact:



Wonder?

Pay attention to what I said above:

That's #define是在预处理的时候进行直接替换! (This sentence is the focus of this section)

In other words, the above if (false) ... Here is:

if (false) print (); Send (); cout << "Hello World" <<endl;

you understand.

How to solve, some people immediately think, with {...} It is not possible to enclose the value of # define. Indeed, it is possible here.

We used to write code with a semicolon on the right side of the statement, and if we use {} In a macro, we would usually write:

#define LOG {print (); Send ();};
What if there is an else behind our if?

It becomes:

if (false) {print (); Send ();}; Else{cout << "Hello" <<ENDL;}

This is because the IF statement is added later, and the compilation does not pass. Do not say you say, that I do not add, if you develop a large project you do not know that you do not want to add, you will be dizzy , so unified norms are important .

So come our final version: Do{...} while (0);

#define LOG do{print (); Send ();} while (0); int main () {if (false) logelse{cout << "Hello" <<ENDL;} cout << "Hello World" <<endl;system ("pause"); return 0;}


is equivalent to:

if (false) Do{print (); Send ();} while (0); else{cout << "Hello" <<ENDL;} cout << "Hello World" <<endl;

Use do{...} while (0), wrap the # define that you want to operate, no matter how you operate outside, it will not affect the operation of # define. Wonderful and wonderful.


Three. Replace Goto.

int dosomething () {return 0;} int clear () {}int foo () {int error = dosomething (); if (Error = 1) {goto END;} if (Error = 2) {goto END;} End:clear (); return 0;}

Of Course this is just a simple example, some people say, I can not goto, in every goto call place directly, then add a judgment, you have to add a clear (), in case you miss it? And under normal circumstances, if there are a lot of Foo, you have to write a lot of goto,end inside the logic is more complex. This is more to be careful.


Because Goto does not conform to the structure of software engineering, and it is possible to make the code difficult to understand, so many people do not advocate the use of this time, you can use Do{}while (0) for unified management:

int foo () {do {int ' ERROR = dosomething (); if (Error = 1) {break;} if (Error = 2) {break;}} while (0); clear (); return 0;}

is not looking much better, but also to avoid serious bugs caused by errors (such as you in clear is to clean up the memory of the operation, you forgot to write Goto, but not the end inside).

In the do{...} while (0) inside, you can break out of any place and proceed to the following execution logic. Even if you do not write a break, you will run out of do after doing, while (0) not enough to jump out.



Do{...} Use of while (0)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.