Min macro definition Exploration

Source: Internet
Author: User

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 :?, ? Returns a larger value of the two operands. The min defined by the two operators is as follows:
# Define min (x, y) (x) # 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
Type min (type A, type B)
{
Return a <B? A: B;
}
Source: http://www.chinaunix.net/jh/23/934870.html
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.

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.