代码之家  ›  专栏  ›  技术社区  ›  dimba

C++函数调用标识符

  •  5
  • dimba  · 技术社区  · 15 年前

    void Foo() {
      ......
      LOG_ERROR("I'm error 1")   // call 1
      .....
      LOG_ERROR("I'm error 2")  // call 2
      .....
    
    }
    

    LOG_ERROR() 是宏。 日志错误() 应该打印识别它的字符串 A::Foo() 将保持不变。标识符应保留代码 变化。

    日志错误() 代码。

    __LINE__ 不是答案,因为 Foo() 可以从构建移动到

    所以我想确认一下 日志错误() 相对于起始位置

    • a、 按文件名标识( __FILE__ )+函数名( __FUNCTION__ ) + 的行号 日志错误() Foo()
    • b、 按文件名标识( __文件__ )+函数名( ) + 日志错误() Foo() .

    解决方案应至少与VC++2008和g++4.1.1配合使用。

    link text )是:

    #define ENABLE_LOG_ERROR static const int LOG_ERROR_start_line = __LINE__
    #define LOG_ERROR(s) cerr << "error #" << (__LINE__ - LOG_ERROR_start_line) \
        << " in " << __func__ << ": " << s << endl
    
    void Foo() {
         ENABLE_LOG_ERROR;
         //...
         LOG_ERROR("error 1");
         int i;
         LOG_ERROR("error 2");
    } 
    

    这将强制用户写入 ENABLE_LOG_ERROR 在每个函数的开头包含 日志错误()

    3 回复  |  直到 9 年前
        1
  •  1
  •   Geerad    15 年前

    这个解决方案是 非标准 __COUNTER__ ,每次调用时都会递增。

    #define LOG_ERROR(s) cerr << "error #" << (__COUNTER__) << " in " \
    << __func__ << ": " << s << endl
    

    请注意 __计数器__ 将在每个编译单元中重置,并且仅在每个编译单元中重置。所以如果 Foo() 有7个 LOG_ERROR() 宏,在后面的函数中 Bar() __计数器__ 日志错误() .

        2
  •  1
  •   TheUndeadFish    15 年前

    如果这些假设成立,那么解决方案是让您的程序将其当前版本写入日志文件。然后每个单独的日志条目可以通过 __LINE__ .

    因此,当有人需要使用日志时:他们可以查看日志中的版本号,从源代码控制存储库中获取相应的源代码,并使用日志中的行号转到正确的源代码行。这给使用日志输出的人增加了一些负担。但是,如果记录的代码依赖于其他代码,或者受其他代码的影响,这些代码可能会随着版本的变化而变化,那么可能仍然需要源代码的历史状态。

    此外,这样做的一个好处是,它消除了假设任何给定函数都将保持不变的需要,而这正是问题的一部分。因此该方法具有更广泛的应用前景。


    如果程序版本通常存储在普通源代码中不易访问的地方,那么您可以创建一个预构建步骤,该步骤将提取版本并将其作为#define或const字符串写入一个简单的version.h文件。然后日志代码或宏可以自动使用它来始终输出程序的当前版本。

        3
  •  0
  •   Benjamin Titmus    15 年前

    通过修改堆栈思想,使用 std::map std::string 并查找函数名。

    std::map<std::string, int> LOG_ERROR_count_map;
    #define LOG_ERROR(s) {\
      int count = ++LOG_ERROR_count_map[ __func__ ];\
      std::cout << count << " in " __func__ ": " s << std::endl;\
    }
    

    这意味着你不需要 ENABLE_LOG_ERROR