From min & max, let's have a look at linux design. I admit it's my title. However, I still recommend that you continue reading the data for at most one minute.
Of course, if you can waste more than ten minutes, my goal will be achieved, and you will have a different experience. Q: How do you implement the min & max functions? I think most people have three methods: 1) define macros; 2) define functions; 3) define inline functions. For the second method, needless to say, there will be discounts for such a single function efficiency; for the third method, inline is introduced in the newer C99. In fact, I am looking for reasons. I am too lazy and don't want to discuss the second and third types. I am also hiding the powerful optimization capabilities of modern compilers. Maybe the compiler automatically optimizes small functions into inline functions for you. OK. The theme here is about macro definition and has nothing to do with other theme. See (take min as an example): www.2cto.com 1 # define min (X, Y) (X) <(Y )? (X): (Y) This is a general practice. brackets are added for each symbol, which is satisfactory. What is the problem? For more information, see: 1int x = 1, y = 2; 2 printf ("min = % d/n", min (x ++, y ++); // output min = 23 printf ("x = % d, y = % d/n", x, y); // output x = 3, y = 3
The problem arises. After we originally expected to execute the min operation, x is 2 and y is 3. What happened? let's expand the macro: 1 (x ++) <(y ++ )? (X ++): (y ++? The problem is that x ++ is executed twice. Let's see how the great Linux kernel solves this problem. 01 // include/linux/kernel. h02 03 # define min (x, y) ({/04 typeof (x) _ x = (x);/05 typeof (y) _ y = (y ); /06 (void) (& _ x = & _ y);/07 _ x <_ y? _ X: _ y;}) 08 09 # define max (x, y) ({/10 typeof (x) _ x = (x);/11 typeof (y) _ y = (y);/12 www.2cto.com (void) (& _ x = & _ y);/13 _ x> _ y? _ X: _ y;}) Here is a simple explanation:
1) Purpose of typeof (X): Obtain the type information of X. For example, if typeof (10) is int, double f = 1.0, and typeof (f) is double. 2) ({}) Purpose: in a sentence, there can be many expressions between ({And}), and its value is the value of the last expression. 3) (void) (& _ x = & _ y); this clause is used to determine whether the types of _ x and _ y are the same. If it is of different types, the compiler will give a warning. To put it bluntly, the macro definition first introduces two temporary variables of the same type as x and y, and then calculates the maximum or minimum values of the temporary variables. Author pathenon