【问题标题】:How to check if __PRETTY_FUNCTION__ can be used?如何检查 __PRETTY_FUNCTION__ 是否可以使用?
【发布时间】:2010-11-12 11:54:01
【问题描述】:

...../PluginLoader.h:34: multiple definition of 'Dummy_Func_For_Generating_FUNCTION_NAME_Macro()'

以下代码输出上述错误。我的档案中包含警卫。其他一切都编译得很好。

编辑:我试图实现的是检查是否定义了__PRETTY_FUNCTION__,如果是,则稍后通过FUNCTION_NAME 宏在代码中使用它(用于记录目的)。如果未定义__PRETTY_FUNCTION__,则使用次优,依此类推。然而,我得到的回应让我意识到这是不可能的。那么,如果__PRETTY_FUNCTION__ 和其他所有这些都不是宏,它们是什么?以及如何检查某个实现是否具有其中之一?

    void Dummy_Func_For_Generating_FUNCTION_NAME_Macro()
    {
#ifndef FUNCTION_NAME
    #ifdef __PRETTY_FUNCTION__
        #define FUNCTION_NAME __PRETTY_FUNCTION__
    #elif __FUNCTION__
        #define FUNCTION_NAME __FUNCTION__
    #elif __func__
        #define FUNCTION_NAME __func__
    #else
        #define FUNCTION_NAME ""
    #endif
#endif
    }

【问题讨论】:

  • __PRETTY_FUNCTION____FUNCTION____func__ 的值是多少?
  • @Adrien:这些是预定义的宏,但并非所有编译器都实现了所有宏。
  • 你把这个函数放在标题里了吗?如果头被多次包含,编译器可能会抱怨它多次找到相同的函数。
  • Ask about the goal, not the step. 如果他们不了解您要做什么,那么没有人可以帮助您。所以“这里出了什么问题”是“谁知道?你告诉我们。”据我所知,您的目标是生成编译错误;这里没有错。
  • @GMan:我不想产生编译器错误。我只是想正确定义FUNCTION_NAME。我已经在标题中明确提出了我的问题。

标签: c++ macros c-preprocessor


【解决方案1】:

void Dummy_Func_For_Generating_FUNCTION_NAME_Macro() 是一个函数,而不是宏。函数不创建宏。宏在预处理器阶段解析,函数在编译器阶段解析。删除函数定义,只留下#ifndef块。

使用编译器识别宏来确定要使用哪个函数识别宏。例如:

#ifdef _MSC_VER // Visual Studio
    #define FUNCTION_NAME __FUNCTION__
#endif

【讨论】:

  • __PRETTY_FUNCTION____FUNCTION____func__ 只在函数中定义
  • @Paul R,宏定义应该没有范围
  • 在你真正感兴趣的函数中使用FUNCTION_NAME,而不是在虚拟函数中,它总是会解析为虚拟函数。
  • @Dialectus:我只是确保定义了FUNCTION_NAME。正是因为预处理器在编译器之前运行,所以我可以知道要使用什么宏。
  • 这是不可能的。您必须检查编译器(每个都有特殊的识别宏和版本),而不是检查函数范围宏的存在。
【解决方案2】:

__PRETTY_FUNCTION____FUNCTION__ 不是像 __LINE____FILE__ 这样的预处理器宏,而是魔术常量,它们在预处理器时不可用,但在编译时(在函数范围内)稍后可用。

因此,无论您在此处尝试使用宏做什么,都可能无论如何都行不通。

但是编译错误可能是guard的问题。我成功地编译了一个不太不同的程序(见下文),没有任何问题。但正如我上面所说,FUNCTION_NAME 将始终设置为空字符串。

xx.h 头文件

#ifndef H_XX_H
#define H_XX_H

#ifndef FUNCTION_NAME
    void Dummy_Func_For_Generating_FUNCTION_NAME_Macro()
    {
    #ifdef __PRETTY_FUNCTION__
        #define FUNCTION_NAME __PRETTY_FUNCTION__
    #elif __FUNCTION__
        #define FUNCTION_NAME __FUNCTION__
    #elif __func__
        #define FUNCTION_NAME __func__
    #else
        #define FUNCTION_NAME ""
    #endif
   ;
   }
#endif
#endif

xx.c 源文件

#include <stdio.h>
#include "xx.h"

main(){
    printf("%s\n", FUNCTION_NAME);
}

【讨论】:

  • __GUARD is reserved,别用了。
  • 好的,我猜你不是对__guard 关键字做出反应,而是对双前导下划线做出反应。
  • +1,我没有意识到 PRETTY_FUNCTION 等常量直到编译时才被初始化,回想起来,这似乎很明显:)
【解决方案3】:

我以前也遇到过这个问题,是挂载磁盘造成的:

subst R: C:\Source\

Test.cpp:

 #include "C:\Source\PluginLoader.h"  
 #include "R:\PluginLoader.h"

现在如果你包含 guard is #pragma once,编译器不够聪明,无法知道它们实际上是一个文件,从而导致重新定义错误。

但是,我不确定这是否是您的问题,因为它取决于:

  • 您包括从两个虚拟磁盘, 和物理磁盘
  • 您的包含保护是 #pragma once,而不是宏保护

.

【讨论】:

    【解决方案4】:

    将您的函数放入anonymous namespace。这将消除duplicate function 定义errors。即

     namespace {
         function goes here
      }
    

    【讨论】:

      猜你喜欢
      • 2015-09-30
      • 2015-02-05
      • 2021-11-10
      • 2023-03-08
      • 2012-02-26
      • 2016-01-13
      • 1970-01-01
      • 1970-01-01
      • 2014-08-12
      相关资源
      最近更新 更多