Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

How to understand the structure of C language do {} while (0)

2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/02 Report--

This article mainly introduces "how to understand the structure of C language do {} while (0)". In daily operation, I believe many people have doubts about how to understand the structure of C language do {} while (0). The editor has consulted all kinds of materials and sorted out simple and easy-to-use operation methods. I hope it will be helpful for you to answer the doubts about "how to understand C language do {} while (0) structure"! Next, please follow the editor to study!

In embedded development, macro definitions are very powerful and convenient, and if used correctly, you can get twice the result with half the effort. However, in many C programs, you may see less direct and more special macro definitions, such as do {} while (0).

Do {conditional code} while (condition) structure

The general structure is like the following code

Do {/ / Loop body} while (conditional expression)

The difference between do while/while do

Do while ()

It means to do it first!

While () do

It means to see if you can do it first!

First meet do {...} while (0)

Code like this is often encountered in the linux kernel and other open source code:

Do {...} while (0)

At first glance, this kind of code is not a loop. On the surface, do..while doesn't make any sense here, it's only executed once, so why use it this way?

Seven kinds of wonderful points are summarized.

In fact, do {.} while (0) does more than a little bit, and I list some below.

Sometimes it's more intuitive just to chunk the code than just using {}. For example, in cocos2d-x code

Do {CCImage* pImage = new CCImage (); CC_BREAK_IF (NULL = = pImage); bRet = pImage- > initWithString (text, (int) dimensions.width, (int) dimensions.height, eAlign, fontName, (int) fontSize); CC_BREAK_IF (! bRet); bRet = initWithImage (pImage); CC_SAFE_RELEASE (pImage);} while (0)

two。 In order not to make mistakes when developing macros. If you put it directly in curly braces, you will make a mistake.

For example, suppose you need to define a macro like this:

# define DOSOMETHING () action1 (); action2 ()

The intention of this macro is that when DOSOMETHING () is executed, both action1 () and action2 () will be called. If there is a judgment and then execute the macro, it is as follows:

If (NULL = = pPointer) DOSOMETHING (); else.

In this way, when the macro is preprocessed, it will be expanded directly and placed in curly braces, so the code is actually written as follows:

If (NULL = = pPointer) action1 (); action2 (); else.

There are two problems with this deployment:

Because there are two statements after the if branch, the else branch does not have a corresponding if, and the compilation fails.

Assuming that there is no else branch, the second statement in DOSOMETHING is executed regardless of whether the if test passes or not.

So can you just wrap action1 () and action2 () with {}? For example:

# define DOSOMETHING () {action1 (); action2 ();}

When we write code, we are used to putting a semicolon on the right side of the statement. If we use {} in the macro, the macro will be written like this after the code is compiled and expanded: {.};, expanded as follows:

If (NULL = = pPointer) {action1 (); action2 ();}; else.

In this code, there is a semicolon after the curly braces. If there is else, then else does not have a corresponding if, and there is an error in compilation.

So here's the way.

If we use do {...} while (0) to define macros, that is:

# define DOSOMETHING ()\ do {\ action1 ();\ action2 ();\} while (0)\

After the macro is expanded, the above invocation statement retains the initial semantics, and most compilers are able to recognize and optimize useless loops such as do {.} while (0) without reducing performance optimization.

Summary

"macros that let you define always work in the same way, no matter how semicolons and curly braces are used in the calling code, and the macro always ensures that its behavior is consistent.

3. When you are halfway through the execution of a piece of code and want to skip the other half, you can do this with break if you are in the do {...} while (0) loop.

Do {execute. And then execute... If (if any conditions are met) {I want to skip to another piece of code, the rest will not be executed, but the Goto statement is not recommended, what should I do? Break;/* got it * /} I could be executed. } while (false)

An example is as follows

Do {if (! a) break; / / do something here if (! B) break; / / do another thing here} while (0)

4. Some companies do not allow the use of goto for deformed goto. In some functions, you need to implement conditional transfer, or form a loop and jump out of the body of the loop. Using goto is always a simple way, such as:

# include # include int main () {char * str; / * initial memory allocation * / str = (char *) malloc (15); if (str! = NULL) goto loop; printf ("hello world\ n"); loop: printf ("malloc success\ n"); return (0);}

But because goto does not conform to the structure of software engineering and may make the code difficult to understand, many people do not advocate using it, so we can use do {.} while (0) to do the same thing:

# include # include int main () {do {char * str; / * initial memory allocation * / str = (char *) malloc (15); if (str! = NULL) break; printf ("hello world\ n");} while (0); printf ("malloc success\ n"); return (0);}

Here, the body of the function is included with do {.} while (0), and break is used instead of goto. The subsequent clean-up work after while can now achieve the same effect, and the readability and maintainability of the code are much better than the goto code above.

5. It can be compatible with various compilers.

Int a; a = 10; int b; b = 20

This kind of code cannot be compiled on compilers that only support c89, such as ADS 2.0.

Int a; a = 10; do {int b; b = 20;} while (0)

6. Avoid warnings caused by macros empty macros are often used in the kernel due to different architectural limitations. When compiling, these empty macros give a warning. To avoid such warning, we can use do {.} while (0) to define empty macros:

# define DOSOMETHING () do {} while (0)

7. Define a single function block to perform complex operations

If you have a complex function with a lot of variables, and you don't want to add new functions, you can use do {...} while (0) to write your code in it, where you can define variables without considering the repetition of the variable name before or after the function, for example

Int key;string value; int func () {int key = GetKey (); string value = GetValue (); dosomething for key,value; do {int key;string value; dosomething for this key,value;} while (0);} at this point, the study on "how to understand the C language do {} while (0) structure" is over, hoping to solve everyone's doubts. The collocation of theory and practice can better help you learn, go and try it! If you want to continue to learn more related knowledge, please continue to follow the website, the editor will continue to work hard to bring you more practical articles!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report