C++ C++;用于构建类和函数字符串的可移植方法

C++ C++;用于构建类和函数字符串的可移植方法,c++,C++,我正在尝试自动生成可在调试日志中使用的字符串,语法如下: ClassName::FunctionName 源代码可用于具有不同编译器的两个系统,包括: Microsoft Visual Studio 2010, Version 10.0.40219.1 SP1Rel 及 到目前为止,我已经试过了: #if defined(__FUNCDNAME__) #define FNAME __FUNCDNAME__ #elif defined(__FU

我正在尝试自动生成可在调试日志中使用的字符串,语法如下:

    ClassName::FunctionName
源代码可用于具有不同编译器的两个系统,包括:

    Microsoft Visual Studio 2010, Version 10.0.40219.1 SP1Rel

到目前为止,我已经试过了:

    #if defined(__FUNCDNAME__)
      #define FNAME    __FUNCDNAME__
    #elif defined(__FUNCTION__)
      #define FNAME    __FUNCTION__
    #elif defined(__FUNSIG__)
      #define FNAME    __FUNSIG__
    #elif defined(__func__)
      #define FNAME    __func__
    #elif defined(__PRETTY_FUNCTION__)
      #define FNAME    __PRETTY_FUNCTION__
    #else
      #define FNAME    ""
    #endif
然后,我添加了一些测试代码,以便在调试器中看到结果:

    char szTemp[128];
    strcpy_s(szTemp, sizeof(szTemp), FNAME);
结果不是我想要的:

    ??0CLSNAME@@QAE@AAV?$SecBlock@EV?$AllocatorWithCleanup@ES0A@@@@@@0_N@Z
我不知道这是什么

[编辑]我更改了预处理器,使我能够更清楚地了解正在发生的事情,现在代码显示:

    szFrom[0] = '\0';
    #if defined(__PRETTY_FUNCTION__)
      #define FNAME    __PRETTY_FUNCTION__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__FUNCTION__)
      #define FNAME    __FUNCTION__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__FUNCDNAME__)
      #define FNAME    __FUNCDNAME__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__FUNSIG__)
      #define FNAME    __FUNSIG__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__func__)
      #define FNAME    __func__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
使用MSVC时,我可以看到流和丑陋的输出来自FUNCDNAME,这是流进入的唯一条件

[编辑2]最终工作方案:

    szFrom[0] = '\0';
    #if defined(__PRETTY_FUNCTION__)
      #define FNAME    __PRETTY_FUNCTION__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__FUNCTION__)
      #define FNAME    __FUNCTION__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__FUNSIG__)
      #define FNAME    __FUNSIG__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
    #if defined(__func__)
      #define FNAME    __func__
      strcpy_s(szFrom, sizeof(szFrom), FNAME);
    #endif
在MSVC上,这给出了输出:

    ClassName::FunctionName

感谢访问p.W.

如果您想在Visual Studio中以
ClassName::FunctionName
格式打印,则
\uuuu FUNCTION\uu
最合适。因此,您必须将它放在条件包含的层次结构中的第一位(
#ifdef
s)


你可以现场观看。

你被称为装饰名。名称装饰C++特定的东西。 它需要一个链接器,除了唯一的名称。但是在C++中,两个或多个函数可以具有相同的名称。这是调用函数重载

例如:

class
{
    void Function()
    void Function( int i )
    void Function( string s)
}
这是有效的代码。因此编译器根据参数列表和包含的类名修饰函数名。因此,我们在装饰机制之后给出了唯一的名称

以下是一篇文章:

OT,但考虑到您显然在尝试编写可移植代码,我会避免使用任何附件K
*\u s()
函数,例如
strcpy\u s()
。Per:微软为了提高API的采用率而对标准函数[DEPR]的反对,导致了一个广泛的谬论,即对标准函数的每次调用都必然是不安全的,应该用对“更安全的”APISee(cont)的调用来代替,微软Visual Studio实现了早期版本的API。但是,实施不完整,既不符合C11,也不符合原始TR 24731-1。。。由于与规范存在大量偏差,Microsoft实现不能被视为符合要求或可移植。您给出的结果是在VS或QNX上?如果你能在两个平台上都发布结果,这会有所帮助。我也会重新安排顺序,先使用
\uuu PRETTY\u FUNCTION\uuuu
,然后是符合标准的
\uu FUNCTION\uu
,然后是其他。看到了吗?但你也应该试着把它们全部释放出来,看看哪一个适合你的需要。问题可能是
\uuu func\uu
不一定是宏。
#if defined(__FUNCTION__)
    #define FNAME    __FUNCTION__
...
...
#else
    #define FNAME    ""
#endif
class
{
    void Function()
    void Function( int i )
    void Function( string s)
}