[C language note] [macro definition series] obtain the parameter quantity of variable parameter macros

[C language notes] [linux macro definition series] obtain the parameter number of variable parameter macros

linux macro defines a series of contents. Used to record various macro definitions in linux ☺.

Macro definition description

Used to get the actual number of parameters passed by the variable parameter macro.

For example, call COUNT_ARGS(1, 2, 3), we fill in three parameters, and the return value is 3; COUNT_ARGS(1), we fill in a parameter, and the return value is 1.

Implementation code

#define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n
#define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

In macro definition:

X... Used to fill in parameters.

Note: the parameters passed in by this macro cannot exceed 12. If more than 12 parameters are passed in, the macro will return the parameter value of the 13th parameter.

Sample program

int main(int argc, char* argv[])
{
 #define ARG2    arg2

    printf("%d\n", COUNT_ARGS());
    printf("%d\n", COUNT_ARGS(123));
    printf("%d\n", COUNT_ARGS(test, ARG2));
    printf("%d\n", COUNT_ARGS(123, test, ARG2));
    printf("%d\n", COUNT_ARGS(123, test, ARG2, "test"));
    printf("%d\n", COUNT_ARGS(123, test, ARG2, "test", 66));
    
    return 0;
}

After running, the result is

0
1
2
3
4
5

The results are consistent with expectations.

Open precompiled i file to see the macro replacement.

int main(int argc, char* argv[])
{
    printf("%d\n", 0);
    printf("%d\n", 1);
    printf("%d\n", 2);
    printf("%d\n", 3);
    printf("%d\n", 4);
    printf("%d\n", 5);

    return 0;
}

Directly replaced by the corresponding number of parameters passed in.

Implementation process

  1. Let's see first__ COUNT_ Implementation of args

    #define __COUNT_ARGS(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...) _n

    This macro requires at least 14 parameters to be passed, and the return value is the 14th parameter. If the parameter exceeds the 14th, it will be X Let's go.

  2. Next, look at count_ Implementation of args

    #define COUNT_ARGS(X...) __COUNT_ARGS(, ##X, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    The macro itself is at least__ COUNT_ARGS passed 14 parameters and met the macro__ COUNT_ARGS requirements.

    Let's take a look at the actual use.

    Parameter transfer example

    Let's take the case of passing 5 parameters in the above example program as an example:

    COUNT_ARGS(123, test, ARG2, "test", 66)

    Expand to

    __COUNT_ARGS(,123, test, arg2, "test", 66, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    Passed 19 parameters to__ COUNT_ARGS, let's talk to you later__ COUNT_ Correspond to the formal parameters in args:

    _0,  _1,   _2,   _3,     _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...
      , 123, test, arg2, "test", 66, 12, 11, 10,  9,   8,   7,   6,  5, 4, 3, 2, 1, 0

    Can see_ The value of n is equal to 5, and the parameter returned by the macro is 5, which is consistent with the passed in formal parameter.

    Examples without parameters

    Next, let's look at the case where no parameters are passed.

    When we have no parameters to count_ When args is passed, the value of X is null and ##x will be deleted. Here is ## the syntax used. When x is an empty string, it will be deleted together with the first one.

    The effect of expansion is as follows:

    __COUNT_ARGS(, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    There are 14 parameters passed to__ COUNT_ARGS, and then pass the parameters and__ COUNT_ The formal parameters in args are mapped one by one:

    _0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _n, X...
      , 12, 11, 10,  9,  8,  7,  6,  5,  4,   3,   2,   1,  0

    Can see_ The value of n is equal to 0, and the parameter returned by the macro is 0.

    From the above example, we can see that this macro skillfully uses the characteristics of variable parameter macro to put X Put it at the top of the parameter list, and then make it according to the number of parameters_ The value of n is equal to the value of the corresponding number of parameters.

    matters needing attention

    In addition, note that the number of parameters passed in cannot exceed 12. If more than 12 parameters are passed in, the macro will return the parameter value of the 13th parameter.

    Why is the parameter value of the 13th parameter returned here?

    Here is an example

    COUNT_ARGS(123, test, ARG2, "test", 66, 123, test, ARG2, "test", 66, "test", 66, 987, 999)

    Expand to

    __COUNT_ARGS(,123, test, arg2, "test", 66, 123, test, arg2, "test", 66, "test", 66, 987, 999, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)

    Next we'll talk to__ COUNT_ Correspond to the formal parameters in args:

    _0,  _1,   _2,   _3,     _4,  _5,   _6,   _7,   _8,     _9, _10,    _11, _12,  _n, X...
      , 123, test, arg2, "test",  66,  123, test, arg2, "test",  66, "test",  66, 987, 999, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0

    You will find that after more than 12 parameters, regardless of the number of parameters_ n always corresponds to the value of the 13th parameter.

[References]

linux kernel 5.8

/include/linux/kernel.h

Link to this article: https://blog.csdn.net/u012028275/article/details/118853297

Keywords: C Linux kernel

Added by maralynnj on Sat, 15 Jan 2022 10:50:48 +0200