-1

我了解预定义标识符__func__使函数名称可在函数中使用。但是我什么时候需要它?目的之一可以是调试。其他用例是什么?

4

3 回答 3

7

Update: For clarity, since in (portable) C or C++ there is nothing you can do with the name of the current function as "string" (char array), you're pretty much limited to writing that string somewhere - which can all be viewed as diagnostics or "debugging" purposes. Having that said, you might want to come up with some sort of usage for the function name. For example, declarative security, configurable logging (albeit that is "diagnostics" again, etc.).

In fact most descriptions and manuals on the web explicitly mention that the utility of __func__ and (__LINE__and __FILE__ for that matter) is debugging and diagnostics.

Personally I think it is provided to help make "better" assert() outputs possible.


You use that whenever you "programmatically" need to know the name of the current function. That pretty much excludes the debugger, where you have the name (or even context) of the current function by the very means of the debugger available already.

__func__ (or its older, non-standard predecessor __FUNCTION__) is typically used together with the __LINE__ and maybe __FILE__ macros to provide trace or diagnostic output functionality, that automatically includes the current function (and file, line).

#define TRACE(s) \
        do { fprintf(stderr, "%s:%d:%s: %s", __FILE__,  __LINE__, __func__, (s)); \
        } while (0)

You can then use it like this:

int my_func(char* arg1, int arg2)
{
    TRACE("Doing stuff...");

    /* ... */
}

For more information and examples see this Stackoverflow Q&A.

Even for such output-only purposes, the usability of __func__ is pretty limited, as it only includes the "unqualified and unadorned name" of the function. Such that for the above example it will only by "my_func".

In C/C++ that means that for overloaded functions, you will not be able to distinguish them by the value of __func__ alone. The class- and/or namespace-name, if any, is also not included.

Also compilers typically provide non-standard variations that do include the full function signature or other detail (GCC (see __PRETTY_FUNCTION__), Microsoft C/C++ (see __FUNCDNAME__, __FUNCSIG__)).

于 2013-05-28T06:35:18.067 回答
2

我注意到在我的代码中添加这个宏__FILE__极大__LINE__地帮助了阅读我程序日志的人。它还使编写日志函数变得更加容易,因为我不需要对这些值进行硬编码,因为编译器会为我处理这些。

请记住,人们可能无法访问您的应用程序的源代码,在某些情况下,他们只能使用日志跟踪和输出。如果有一种透明的方式让他们知道发生了什么,那就太好了。

于 2013-05-28T06:48:12.860 回答
1

如果它是一个constexpr(它应该是,但至少在当前的 GCC 中不是,不幸的是),它可以被散列并用于实现一个非常简单和高效的(编译时,没有运行时开销)RTTI 系统。

它还可以提供一个更有用的版本,std::type_info::hash_code该版本既不需要链接 RTTI,也没有允许不同调用返回不同值的缺陷。
标准提供的版本(从 C++11 开始)明确地没有提供这样的保证,这使得它除了作为关联容器(例如 )中的键之外的任何东西都毫无用处std::map
鉴于保证不同的调用(至少是相同的二进制文件,或者至少是具有完全相同定义的类型),它会更有用,例如用于序列化。

(是的,我知道哈希函数有冲突。是的,理论上这是一个问题。但是,给定合理数量的位(例如,64)和合理数量的键(例如,几百个),它们很少发生足以在实践中证明不是问题,而且这不是无法验证的。)

于 2013-05-28T09:01:42.423 回答