Token pasting and __LINE__

前端 未结 2 831
我寻月下人不归
我寻月下人不归 2020-12-19 15:20

I\'m writing a simple macro to show TRACE information.

This is what I\'m using ,

#ifdef __DEBUG__
#define TRACE  { PrintErrorMsg(\"Trace exception at         


        
相关标签:
2条回答
  • 2020-12-19 15:34

    You need this kind of silliness, unfortunately.

    #include <stdio.h>
    
    #define TRACE2(f,l) printf("I am at file: " f " and line: " #l "\n")
    #define TRACE1(f,l) TRACE2(f,l)
    #define TRACE() TRACE1(__FILE__, __LINE__)
    
    int main(void)
    {
        TRACE();
        TRACE();
    }
    

    I am at file: test.cpp and line: 9
    I am at file: test.cpp and line: 10

    0 讨论(0)
  • 2020-12-19 15:35

    When you try to stringize something with #x, that x must be a macro parameter:

    #define FOO #__LINE__ /* this is not okay */
    #define BAR(x) #x     /* this is okay */
    

    But you cannot simply say BAR(__LINE__), because this will pass the token __LINE__ into BAR, where it is immediately turned into a string without expansion (this is by design), giving "__LINE__". The same thing happens with the token-pasting operator ##: expansion of their operands never happens.

    The solution is to add indirection. You should always have these in your codebase somewhere:

    #define STRINGIZE(x) STRINGIZE_SIMPLE(x)
    #define STRINGIZE_SIMPLE(x) #x
    
    #define CONCAT(first, second) CONCAT_SIMPLE(first, second)
    #define CONCAT_SIMPLE(first, second) first ## second
    

    Now STRINGIZE(__LINE__) turns to STRINGIZE_SIMPLE(__LINE__) which gets fully expanded to (for example) #123, which results in "123". Phew! I leave STRINGIZE_SIMPLE around on the off chance I want the original behavior. So your code would be something like:

    #include <iostream>
    
    #define STRINGIZE(x) STRINGIZE_SIMPLE(x)
    #define STRINGIZE_SIMPLE(x) #x
    
    #define TRACE()                                                 \
            PrintErrorMsg("Trace exception in " __FILE__            \
                          " at line number " STRINGIZE(__LINE__)    \
                          " in function " __FUNCTION__ ".")
    
    void PrintErrorMsg(const char* str)
    {
        std::cout << str << std::endl;
    }
    
    int main()
    {
        TRACE();
    }
    
    0 讨论(0)
提交回复
热议问题