g++ __FUNCTION__ replace time

后端 未结 7 709
迷失自我
迷失自我 2020-12-20 17:16

Can anyone tell when g++ replaces the __FUNCTION__ \'macro\' with the string containing the function name? It seems it can replace it not until it has check the

相关标签:
7条回答
  • 2020-12-20 17:32

    In C/C++, the preprocessor will turn "my " "name " "is " "Bob" into the string literal "my name is Bob"; since __FILE__ and __LINE__ are preprocessor instructions, "We are on line " __LINE__ will pass "We are on line 27" to the compiler.

    __FUNCTION__ is normally a synonym for __func__. __func__ can be thought of as a pseudo-function that returns the name of the function in which it is called. This can only be done by the compiler and not by the preprocessor. Because __func__ is not evaluated by the preprocessor, you do not get automatic concatenation. So if you are using printf it must be done by printf("the function name is %s", __func__);

    0 讨论(0)
  • 2020-12-20 17:34

    You are using __FUNCTION__ like a preprocessor macro, but it's a variable (please read http://gcc.gnu.org/onlinedocs/gcc/Function-Names.html).

    Try printf("%s", __FUNCTION__) just for testing and it will print the function name.

    0 讨论(0)
  • 2020-12-20 17:34

    __FUNCTION__ is not standard. Use __func__. As the documentation says, it's as if:

    <ret-type> function_name( <args> )
    {
        static const char __func__[] = "function-name";
        ...
    
    0 讨论(0)
  • 2020-12-20 17:36
    printf("%s" __FILE__ __LINE__ "\n", __FUNCTION__);
    

    Yeah, I know that's not really the same.

    0 讨论(0)
  • 2020-12-20 17:37

    Is this what you want?

    #include <stdio.h>
    
    #define DBG_WHEREAMI(X) printf("%s %s(%d): %s\n",__func__,__FILE__,__LINE__,X)
    
    int main(int argc, char* argv)
    {
      DBG_WHEREAMI("Starting");
    }
    

    Note: Since you marked this as C++ you should probably be using the iostreams to make sure it's type safe.

    0 讨论(0)
  • 2020-12-20 17:46

    Note that if you create a class, you can build a message from any number of types as you'd like which means you have a similar effect to the << operator or the format in a printf(3C). Something like this:

    // make sure log remains copyable
    class log
    {
    public:
      log(const char *function, const char *filename, int line)
      {
        f_message << function << ":" << filename << ":" << line << ": ";
      }
      ~log()
      {
        //printf("%s\n", f_message.str().c_str()); -- printf?!
        std::cerr << f_message.str() << std::endl;
      }
    
      log& operator () (const char *value)
      {
        f_message << value;
      }
      log& operator () (int value)
      {
        f_message << value;
      }
      // repeat with all the types you want to support in the base class
      // (should be all the basic types at least)
    private:
      sstream f_message;
    };
    
    // start the magic here
    log log_error(const char *func, const char *file, int line)
    {
      log l(func, file, line);
      return l;
    }
    
    // NOTE: No ';' at the end here!
    #define LOG_DEBUG  log_error(__func__, __FILE__, __LINE__)
    
    // usage sample:
    LOG_DEBUG("found ")(count)(" items");
    

    Note that you could declare the << operators instead of the (). In that case the resulting usage would be something like this:

    LOG_DEBUG << "found " << count << " items";
    

    Depends which you prefer to use. I kind of like () because it protects your expressions automatically. i.e. if you want to output "count << 3" then you'd have to write:

    LOG_DEBUG << "found " << (count << 3) << " items";
    
    0 讨论(0)
提交回复
热议问题