This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C Concatenation Operator (##) Error

Hi,

I am trying to get a macro working.  I didn't create the macro but it looks easy enough to debug.  This is what I am seeing:

Macro call:

    CSL_FINST(ECAP_Ptr->ECCTL1, ECAP_ECCTL1_FREE_SOFT, STOP );

Macro definitions:

    #define CSL_FINST(reg, PER_REG_FIELD, TOKEN)                                \
        CSL_FINS((reg), PER_REG_FIELD, CSL_##PER_REG_FIELD##_##TOKEN)

    #define CSL_FINS(reg, PER_REG_FIELD, val)                                   \
        ((reg) = ((reg) & ~CSL_##PER_REG_FIELD##_MASK))

I get a compiler error: #18 expected a ")".


Does anyone got an idea why it's giving me this weird error?

I noticed that it compiles when I changed it to:

    CSL_FINST(ECAP_Ptr->ECCTL1, ECAP_ECCTL1_FREE_SOFT_MASK, STOP );

It looks like it didn't like the second ## operator in the CSL_FINS macro. 

The code worked on the TI v7.3.1 C674x Compiler using CCS 5.1, but I am using the TI v7.4.1 Compiler on CCS 5.3 now.  Even if I changed it to the TI v7.3.1 it doesn't compile either.  Not sure if some compiler switches that are preventing it from compiling on my new build.

Thanks.

  • I figured it out.  The expansion worked differently than I expected.

    I made the following changes to my macros:

        #define CSL_FINST(reg, PER_REG_FIELD, TOKEN) \

            CSL_FINS((reg), ##PER_REG_FIELD, PER_REG_FIELD##_##TOKEN)

        #define CSL_FINS(reg, PER_REG_FIELD, val) \

            ((reg) = ((reg) & ~PER_REG_FIELD##_MASK)|CSL_FMK(##PER_REG_FIELD, val))

    I turned on the preprocessor options to output the preprocessor and that helped me a lot in my debug because I was now able to see the actual issue.

     

  • Hi Lam,

    This post will help other community members. Thank you for the update.

  • #define CSL_FINST(reg, PER_REG_FIELD, TOKEN) \

            CSL_FINS((reg), ##PER_REG_FIELD, PER_REG_FIELD##_##TOKEN)

    #define CSL_FINS(reg, PER_REG_FIELD, val) \

            ((reg) = ((reg) & ~PER_REG_FIELD##_MASK)|CSL_FMK(##PER_REG_FIELD, val))

    What is the intent of the first and last ## operators here?  It is usually considered a bad idea to token-paste a comma or open-parenthesis with a macro argument: it can (or always does?) generate an invalid token for the next (logical) parsing pass.  Some compilers do not detect the problem, but others do.