跨平台定义宏__FUNCTION__和__func__的#define宏。

20

使用gcc 4.4.2和WinXP中的Visual Studio C++ 2008进行编译

#if defined ( WIN32 )
#define __FUNCTION__ __func__
#endif

我想要使用宏来显示函数名。我已经完成了上述操作,以便于跨平台,在linux或windows编译时使用相同的func

然而,在WinXP上编译时,我遇到了以下错误:

__func__ undeclared identifier

我能不能不这样定义宏?

非常感谢任何建议,


5
应该使用#if defined(_MSC_VER)而不是#if defined(_WIN32)。问题不在于你使用的操作系统,而在于你使用的编译器。 - Dale Wilson
4个回答

26

看起来你的#define反了。如果你想在两个平台上都使用__func__,而WIN32有__FUNCTION__但没有__func__,那么你需要这样做:

#if defined ( WIN32 )
#define __func__ __FUNCTION__
#endif

也许有更好的方法来判断是否需要定义__func__,但这个小技巧应该能解决问题。

请记住,在支持__FUNCTION____func__关键字的编译器上,它们不是宏,所以您不能执行以下操作(因为#ifndef __func__无效):

#ifndef __func__
#define __func__ __FUNCTION__
#endif

来自C99规范:

6.4.2.2 预定义标识符

1 标识符__func__应被编译器隐式声明,并在每个函数定义的左花括号后立即声明如下:

static const char __func__[] = "function-name";

出现在函数名为词法封闭函数的名称的位置。


谢谢,那个方法可行。但是让我思考了一下。当你说__FUNCTION__和__func__不是宏时,为什么不能在#define中定义呢?另外,我们如何知道它是宏还是关键字?非常感谢。 - ant2009
1
这是一个好问题 - 我想你必须去ANSI规范(或谷歌)找出答案。在这种情况下,__func__是一个“预定义标识符”,根据描述,它的作用类似于在函数中定义的静态const变量。在我上面的示例中,不起作用的部分是#ifndef __func__,因为__func__不是宏预处理器可见的已定义宏。 - tomlogic

6
< p > __FUNCTION__宏在MSVC编译器中预定义。您需要将其设置为以下格式:

#ifndef _MSC_VER
#define __FUNCTION__ __func__
#endif

或者,如果您更喜欢这种方式:
#ifdef _MSC_VER
#define __func__ __FUNCTION__
#endif

我尝试过了,仍然得到相同的错误。我也在条件(MSVC)中尝试了这个,但还是得到了相同的错误。还有其他建议吗?谢谢。 - ant2009
也许是我自己的问题,但当我尝试这两个时,我遇到了错误:"#if[n]def 期望一个标识符"。谢谢。 - ant2009
@robUK - 哎呀,原始代码让我陷入了麻烦。已经修复了。 - Hans Passant
谢谢,我应该看到括号的。我想我太习惯使用带括号的if defined()了。 - ant2009

2

在支持C99的任何编译器中,您应该能够使用__func__而无需任何显式的宏。


1
是的,我可以在c89/c99中使用它。然而,Visual Studio 2008使用__FUNCTION__。我尝试使用#define,以便我可以在Windows和Linux上使用相同的宏。谢谢。 - ant2009

1

你当然可以使用#define定义这样的宏。每个FUNCTION实例都将被替换为__func__。但是,显然你的编译器不认识__func__。我相信VC知道__FUNCTION__,所以

#if defined ( WIN32 )
#  define __func__ __FUNCTION__
#endif

可能会做。


__FUNCTION__不是宏,因此您无法在其上使用#ifdef。与__func__一样,它要么是编译器的关键字,要么就不是。 - tomlogic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接