In this series of articles, I mainly wrote some clever code snippets that I was concerned about when I was reading the Linux kernel. (I did not pay attention to the design ideas of various modules of the OS, I want to write this part in the "deep understanding of Linux Kernel" series). I will review the C language and assembly language syntax through the Kernel code, secondly, we will learn the style and ideas of writing code by kernel developers.
In the Kernel File include/linux/bug. h, there are two macro definitions:
| 23456
|
| E.g. in a structure initializer (or where-ever else comma expressionsAren't permitted ).*/
In the first analysis, it indicates: Check whether expression e is 0, 0 is compiled, and 0 is returned. If expression e is not 0, the compilation fails.
It may be easy to understand the error from the macro name, or change to "BUILD_BUG_OR_ZERO", which is better because someone who is discussing this also submits this patch (http://lkml.indiana.edu/hypermail/linux/kernel/0703.1/1546.html) but is not accepted by the community. Regardless of the macro definition name, let's gradually analyze how the macro is implemented:
Sizeof (struct {int :-!! (E );}))
1. (e): Declaration of expression e
2 .!! (E): Calculate the result of e twice. That is, if e is 0, the result is 0. If e is not 0, the result is 1.
3 .-!! (E): multiply by-1. If the result of step 1 is 0, it is still 0; otherwise, the result is-1.
4. struct {int :-!! (0) ;}--> struct {int: 0 ;}: if the result of e is 0, we declare that a struct has an int-type data field, and the number of places it occupies is set to 0. There is no problem, and we think everything is normal.
5. struct {int :-!! (1) ;}--> struct {int:-1 ;}: if the result of e is not 0, the bit field of the int data field of the struct will become a negative number, it is a syntax error to declare the bitfield as a negative number.
6. now, either the result is a struct with a single field of 0 declared, or an error occurred while compiling the bitfield with a negative number. If the structure can be correctly compiled, we will perform the sizeof operation on the struct, obtain the result of size_t type. The value is 0.
To sum up, BUILD_BUG_ON_ZERO (e) indicates that if the expression e result is 0, It is compiled and the macro value is 0. If the expression e result is not 0, the compilation fails.
This will be reminiscent of the use of assert Macros in C:
Void assert (int expression );
If the value of expression is 0, it prints an error message to stderr and terminates the program by calling abort. Otherwise, the asserted is true and the execution continues.
The essential difference between macros and assert is that our macros are tested at compilation, while assert macros are tested at runtime. We hope to capture errors during compilation as early as possible, rather than delaying the running. In my opinion, this macro usage is called "compile-time assertions", and assert is "runtime assertions ".
After understanding the above, let's take a look at the second BUILD_BUG_ON_NULL (e) Macro. Similar to the first macro, it is used to assert whether e is NULL during compilation. If this macro is returned (void *) 0 (that is, the difference between NULL and the first macro); if it is not NULL, an error occurs during compilation.
In addition to the above two compilations, there are several other ideas in the include/linux/bug. h file, such:
BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2*!!(condition)])) BUILD_BUG_ON_NOT_POWER_OF_2(n) \ == || (((n) & ((n) - )) != ))
For the description, see the description of macro definitions in the file.
--------------------------------
References:
Detailed description of structural position domain in C language of http://blog.csdn.net/jiyucn/article/details/862085
Sizeof related issues in http://blog.csdn.net/jiyucn/article/details/862062 C Language
Description of http://www.cplusplus.com/reference/cassert/assert/ assert usage
Http://stackoverflow.com/questions/9229601/what-is-in-c-code questions and answers are from Stackoverflow