【问题标题】:Why is constant char pointer at beginning of every function used?为什么在每个函数的开头都使用常量 char 指针?
【发布时间】:2025-12-07 06:50:01
【问题描述】:

第一行函数的目的是什么?

void  foo::bar()

{

  const char * function_name = "bar"; // <<< WHY??

  /* Code */

  /* More Code */

  /* Waiting for function_name to be used !!!*/

  /* Wow it is totally useless?*/
  return; 
}

`

这在有经验的人设计的代码中无处不在,没有要打印的宏。它有什么技巧吗?

【问题讨论】:

  • 你能举一个例子来说明这是常见的用法吗?也许链接到一个开源项目?我只在它用于日志记录的情况下看到这样做,因此有时仍然存在于没有日志的小函数中。
  • 这是一个只有把它放在那里的人才能回答的问题(我怀疑它是一个调试辅助工具,或者与一个曾经存在的宏有关)
  • @BoBTFish 不幸的是,这是在专有代码中。我搜索了打印为“FUNCTION”的调试宏,但没有。由于它没有被使用,编译器对 O1 本身充满信心地删除了它。其他所有编写代码的人都遵循相同的文化

标签: c++


【解决方案1】:

有可能在某一时刻,该函数的代码如下所示:

const char * function_name = "bar";
Loggers::get_logger() << "Entered function " << function_name << "\n";

作为编写企业代码的人,我经常看到类似的结构。也许日志被删除或元编程模板的一部分,虽然考虑到它使用const char * 来存储字符串,但我不得不假设代码很旧。

无论如何,这段代码没有任何内容是特定于 C++ 的设计选择,如果您想要一个明确的答案,您需要询问编写代码的特定人员。

【讨论】:

  • 如果您事先知道您永远不会对特定字符串字面量进行任何操作,而是将其逐字传递给 [可以] 采用 const char * 的 API,然后使用 const char * 变量 cut 引用它出一团开销。如果只有一个,没什么大不了的,但如果每个函数都有一个,那可能是你不需要的数千个静态构造函数。
【解决方案2】:

我怀疑这个程序的头文件在某处包含一个自定义的assert 宏,读取类似

#define fooco_assert(expr) \
    ((void) ((expr) || \
     fooco_assert_failed(#expr, __FILE__, __LINE__, function_name)))

extern int fooco_assert_failed(const char *expr, const char *srcfile,
                               int lineno, const char *fnname);

为了支持这一点,作者制定了一个样式规则,即在每个函数的开头都有一个function_name 的定义,以便他们将来可以根据需要添加对fooco_assert 的调用,而无需不得不考虑function_name 是否可用。正如您所注意到的,除非实际使用它们,否则编译器不会费心将字符串发送到已编译的程序中,因此这不是效率问题。

当然, 是阅读和编辑程序的加速器。 C++11 编译器提供了一个名为__func__ 的预定义变量,其中包含当前函数的名称;这可以代替使用。该特性于 1999 年被添加到 C 标准中,许多 C++ 编译器几乎立即采用了它。其他 C++ 编译器没有 __func__,但有等效的专有扩展,例如__FUNCTION__。请注意,这些是不是宏;

#ifndef __func__
#define __func__ "<unavailable>"
#endif

不会检测__func__ 是否可用。您将不得不做这样的事情(在我的脑海中,根本没有经过测试):

#if __cplusplus >= 201103L || __GNUC__ >= 3
// __func__ is available in C++11, and in GCC >= 3.0
#elif _MSC_VER || __GNUC__
// pre-C++11 MSVC and ancient versions of GCC call this
// feature __FUNCTION__ instead
#define __func__ __FUNCTION__
#elif ...
// ... etc etc for all other compilers you care about 
#else
#define __func__ "<unavailable>"
#endif

【讨论】:

  • 惊讶的 func 仅在 C++11 中引入!
  • @P.P.它于 1999 年被添加到 C 中,但 C++ 标准在 1998 年至 2011 年间只收到了小幅修订。不过,许多 C++ 编译器确实提前采用了它,或者它们具有等效的扩展;我会补充一点。