The ## operator in C

后端 未结 7 2074
花落未央
花落未央 2020-12-06 17:02

What does ## do in C?

Example:

typedef struct
{
    unsigned int bit0:1;
    unsigned int bit1:1;
    unsigned int bit2:1;
    unsigned          


        
相关标签:
7条回答
  • 2020-12-06 17:09

    It's called the pasting operator; it concatenates the text in bt with the text bit. So for example, if your macro invocation was

    REGISTER_BIT(x, 4)
    

    It would expand to

    ((volatile _io_reg*)&x)->bit4
    

    Without it, you couldn't put a macro argument directly beside text in the macro body, because then the text would touch the argument name and become part of the same token, and it'd become a different name.

    0 讨论(0)
  • 2020-12-06 17:15

    The operator ## concatenates two arguments leaving no blank spaces between them:

    #define glue(a,b) a ## b
    glue(c,out) << "test";
    
    0 讨论(0)
  • 2020-12-06 17:15

    It's not a C construct, it's a preprocessor feature. In this case it's meant to evaluate the bt variable and concatenate it with the bit prefix. Without the hashes you would have bitbt there, which obviously would not work.

    0 讨论(0)
  • 2020-12-06 17:19

    That's part of the macro definition.

    It allows you to concatenate strings inside the macro.

    In your case, you can use bt from 7 to 0 like this:

    REGISTER_BIT(myreg, 0)
    

    and it will be expanded as:

    ((volatile _io_reg*)&myreg)->bit0

    Without this, you'd have to define the bit part of the macro as one of the macro's arguments:

    #define REGISTER_BIT(rg,bt) ((volatile _io_reg*)&rg)->bt
    

    where the usage would be:

    REGISTER_BIT(myreg, bit0)
    

    which is more cumbersome.

    This also allows you to build new names.

    Assume you have these macros:

    #define AAA_POS 1
    #define AAA_MASK (1 << AAA_POS)
    #define BBB_POS 2
    #define BBB_MASK (1 << BBB_POS)
    

    and you want a macro that extracts AAA from a bit vector. You can write it like this:

    #define EXTRACT(bv, field) ((bv & field##_MASK) >> field##_POS)
    

    and then you use it like this:

    EXTRACT(my_bitvector, AAA)
    
    0 讨论(0)
  • 2020-12-06 17:20

    That is the token pasting operator.

    0 讨论(0)
  • 2020-12-06 17:22

    Here's an example from ffmpeg, a macro that registers both audio and video filters:

    #define REGISTER_FILTER(X, x, y)                                        \
        {                                                                   \
            extern AVFilter ff_##y##_##x;                                   \
            if (CONFIG_##X##_FILTER)                                        \
                avfilter_register(&ff_##y##_##x);                           \
        }
    

    and usage can be:

    REGISTER_FILTER(AECHO,aecho,af);
    REGISTER_FILTER(VFLIP,vflip,vf);
    
    0 讨论(0)
提交回复
热议问题