Min and Max functions in Linux Kernel

Source: Internet
Author: User
These days, in order to sort out the driver knowledge that ldd3 learned some time ago, I went to look at the USB driver. I don't know, but I was shocked. There are a lot of syntaxes in it, which I found to be great at using. It's not like writing code as we usually do. The code in it is really good. However, it is not easy to understand what is inside. When I saw the usb_stor_access_xfer_buf function today, I wanted to see if the min function was written according to what we wrote. But it's silly. I haven't used some other things yet, so I need to Google it. What is the code below? You can go to, include/Linux/kernel. h to find it. Don't look for something, so I'll paste it here. /*

* Min ()/MAX () macros that also do

* Strict type-checking .. see

* "Unnecessary" pointer comparison.

*/

# Define min (x, y )({\

Typeof (x) _ x = (x );\

Typeof (y) _ y = (y );\

(Void) (& _ x = & _ y );\

_ X <_ y? _ X: _ y ;}) # define max (x, y )({\

Typeof (x) _ x = (x );\

Typeof (y) _ y = (y );\

(Void) (& _ x = & _ y );\

_ X> _ y? _ X: _ y;}) When I Google this function, many people have read it. It seems that I am out. This is all due to University accounts. The so-called "getting out and mixing will be paid back sooner or later." Fortunately, I started learning today. Let's take a look at a brother's understanding. He spoke very well. Http://blog.chinaunix.net/u/24474/showart_1101969.html min macro definition Exploration

We recommend that you use the following min macro definition in the GCC document:
Reference: # define min (x, y )\
(_ Extension __\
({\
Typeof (x) _ x = (x), _ y = (y );\
(_ X <__ y )? _ X :__ y ;\
})\
)


This article discusses the significance of this practice.
1. Side effects of traditional min
2. ({Statement List}) Extension in GCC
3. typeof (expression)
4. _ extension _
5. Use typeof and ({}) to implement min, avoiding side effects


Appendix 1. Solutions in the earlier version of GCC

Appendix 2. How to Use template in C ++


1. Side effects of traditional min


Min is usually defined as a macro like this:

# Define min (x, y) (x) <(y )? (X): (y ))


This definition has some side effects. For more information, see the following example:


Int x = 1, y = 2;

Int main ()

{

Printf ("min = % d \ n", min (x ++, y ++ ));

Printf ("x = % d, y = % d \ n", x, y );

}


After the execution of min (x ++, y ++), we expect the value of X to be 2, and the value of Y to be 3.


However, the actual result is that after the mini (x ++, y ++) is executed, the value of X is 3, and the value of Y is 3, the reason is that X ++ was executed twice after the macro scale was launched:


Reference:

Int x = 1, y = 2;

Int main ()

{

Printf ("min = % d \ n", X ++ <y ++? X ++: Y ++ );

Printf ("x = % d, y = % d \ n", x, y );

}


2. ({Statement List}) Extension in GCC

({Statement List}) is an expression. The comma expression is similar, but it is more powerful ({And }) it can contain multiple statements (variable definitions and complex control statements). The value of this expression is the value of the last statement in the Statement List. For example:


Int main ()

{

Int result = ({

Int I, sum = 0;

For (I = 1; I <= 100; I ++)

Sum + = I;

SUM;

})


Printf ("result = % d \ n", result );

}


Running result:

Result = 5050.


3. typeof (expression)
Typeof (expression) is used to obtain the expression type. For example:


Int main ()

{

Int integer;

Typeof (100) I;/* expression 100 is of the int type and defines the int type variable I */

Typeof (integer) J;/* The expression integer is of the int type and defines the int type variable J */


I = 1;

J = 2;

}


4. _ extension _
GCC introduces many extensions not available in Standard C, such as ({And)}. GCC provides the pednatic option to check whether the program uses GCC extensions, when you use the pedantic option to compile the following program:


Int main ()

{

Int result = ({

Int I, sum = 0;

For (I = 1; I <= 100; I ++)

Sum + = I;

SUM;

})


Printf ("result = % d \ n", result );

}


The compiler sends a warning:

$ CC-pedantic test. c

Test. C: In the 'main' function:

Test. C: 9: Warning: iso c does not allow curly braces in expressions.


The compiler reminds programmers that this C program uses a syntax that does not conform to the iso c standard. If other compilers (non-GCC) are used to compile this code, errors may occur. After the _ extension _ keyword is added before all expressions that use the GNU extension keyword, the compiler will not issue a warning when the pedantic option is used for compilation:


Int main ()

{

Int result = _ extension __({

Int I, sum = 0;

For (I = 1; I <= 100; I ++)

Sum + = I;

SUM;

})


Printf ("result = % d \ n", result );

}


$ CC-pedantic test. c

$ Compiled successfully!


5. Use typeof and ({}) to implement min, avoiding side effects


# Define min (x, y )\

({\

Typeof (x) _ x = (x), _ y = (y );\

(_ X <__ y )? _ X :__ y ;\

})


An example of problems that may occur when using traditional min:


Int x = 1, y = 2 ;;

Int main ()

{

Printf ("min = % d \ n", min (x ++, y ++ ));

Printf ("x = % d, y = % d \ n", x, y );

}


It is extended

Reference:

Int x = 1, y = 2 ;;

Int main ()

{

Printf ("min = % d \ n ",({

Typeof (x) _ x = (x ++), _ y = (Y ++);/* defines two integer variables */

(_ X <__ y )? _ X :__ y;

})

);

Printf ("x = % d, y = % d \ n", x, y );

}



During the execution of min (x ++, y ++), X ++ and Y ++ only run once, so the result is correct.


Appendix 1. Solutions in the earlier version of GCC

The earlier version of GCC provides two built-in operators: <? And> ?, <? Returns a smaller value of two operands,>? Returns a larger value of the two operands. The min defined by the two operators is as follows:


# Define min (x, y) (x) <? (Y ))

# Define max (x, y) (x)>? (Y ))

However, the new GCC document states that these two operators are outdated and we recommend that you do not use them.


Appendix 2. How to Use template in C ++
Template <class type>
Type min (type A, type B)
{
Return a <B? A: B;
}



Add Linux kernel min, Max define:

Include/Linux/kernel. h

/*
* Min ()/MAX () macros that also do
* Strict type-checking .. see
* "Unnecessary" pointer comparison.
*/
# Define min (x, y )({\
Typeof (x) _ x = (x );\
Typeof (y) _ y = (y );\
(Void) (& _ x = & _ y );\
_ X <_ y? _ X: _ y ;})

# Define max (x, y )({\
Typeof (x) _ x = (x );\
Typeof (y) _ y = (y );\
(Void) (& _ x = & _ y );\
_ X> _ y? _ X: _ y ;})

Min and Max macros:

  

/*

* Min ()/MAX () macros that also do

* Strict type-checking .. see

* "Unnecessary" pointer comparison.

*/

# Define min (x, y) ({typeof (x) _ x = (x); typeof (y) _ y = (y); (void) (& _ x = & _ y); _ x <_ y? _ X: _ y ;})

# Define max (x, y) ({typeof (x) _ x = (x); typeof (y) _ y = (y); (void) (& _ x = & _ y); _ x> _ y? _ X: _ y ;})

/*

*. And if you can't take the strict

* Types, you can specify one yourself.

*

* Or not use min/max at all, of course.

*/

# Define min_t (type, x, y) ({type _ x = (x); Type _ y = (y); _ x <_ y? _ X: _ y ;})

# Define max_t (type, x, y) ({type _ x = (x); Type _ y = (y); _ x> _ y? _ X: _ y ;})

It doesn't feel a little different from what we use:

(Void) (& _ x = & _ y );

(Void) (& _ x = & _ y) The statement itself is a nonsense in terms of program execution. Its role is, in itself, we cannot perform this operation typeof (_ x) = typeof (_ y). Therefore, it is obviously impossible to determine whether the two address pointers are equal, however, if the _ x and _ y types are different, the pointer types will be different. If two different pointer types are compared, a compilation warning will be thrown. That is to say char * P; int * q; then p = Q;, this judgment will generate a warning during compilation because one is char * and the other is int. Clever here.

Because the kernel is developed together by many developers, there are some other implementations, just like what we usually use:

# Define min (A, B) (a) <(B ))? (A): (B ))

Imagine:

Min (++ A, ++ B) ==> (++ A) <(++ B ))? (++ A) :( ++ B)

Is there a problem? The input parameter is added twice.
Well, I just collected some other people's things. Do you understand the ({Statement List}) extensions in GCC now? It should be basically understandable. Then work hard, the road is long and its repair distance, the original address: http://blog.chinaunix.net/uid-23247212-id-99921.html
Related Article

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.