将__func__视为字符串文字而不是预定义的标识符 [英] Treating __func__ as a string literal instead of a predefined identifier
问题描述
我正在使用gcc编译C99代码.我想编写一个宏,该宏将返回包含函数名称和行号的字符串.
I am using gcc to compile C99 code. I want to write a macro which will return a string containing the function name and line number.
这就是我所拥有的:
#define INFO_MSG __FILE__ ":"__func__"()"
但是,当我编译尝试使用此字符串的代码时,例如:
However, when I compile code which attempts to use this string, for example:
char buff[256] = {'\0'}
sprintf(buff, "Something bad happened here: %s, at line: %d", INFO_MSG, __LINE__);
printf("INFO: %s\n", buff);
我收到以下错误消息:
error: expected ‘)’ before ‘__func__’
我已将问题归结为宏.当我从宏中删除__func__
时,代码可以正确编译.
I have tracked the problem down to the macro. as when I remove __func__
from the macro, the code compiles correctly.
如何修复宏,以便可以在字符串中包含预定义的__func__
宏?
How do I fix the macro, so that I can include the predefined __func__
macro in my string?
推荐答案
从您的评论来看,目标是要有一个宏,它将文件名和函数名(可能还有行号)组合成一个单个字符串,该字符串可以是作为参数传递给printf()
或strcpy()
或syslog()
之类的函数.
Judging from your comments, the objective is to have a macro which combines the file name and function name (and maybe line number) into a single string that can be passed as an argument to functions such as printf()
or strcpy()
or syslog()
.
不幸的是,我认为这是不可能的.
Unfortunately, I don't think that's possible.
C11标准说:
ISO/IEC 9899:2011§6.4.2.2预定义标识符
¶1标识符__func__
应由翻译器隐式声明,就像在每个函数定义的大括号后面紧接着声明一样.
¶1 The identifier __func__
shall be implicitly declared by the translator as if, immediately following the opening brace of each function definition, the declaration
static const char __func__[] = "function-name";
出现,其中function-name是词法包围的函数的名称.
appeared, where function-name is the name of the lexically-enclosing function.
因此,与__FILE__
或__LINE__
不同,__func__
不是宏.
Therefore, __func__
is not a macro, unlike __FILE__
or __LINE__
.
相关问题 __PRETTY_FUNCTION__
和__func__
?
The related question What's the difference between __PRETTY_FUNCTION__
, __FUNCTION__
, __func__
? covers some alternative names. These are GCC-specific extensions, not standard names. Moreover, the GCC 4.8.1 documentation says:
这些标识符不是预处理器宏.在GCC 3.3和更早版本中,仅在C语言中,
__FUNCTION__
和__PRETTY_FUNCTION__
被视为字符串文字.他们可以被使用 来初始化char数组,并且可以将它们与其他字符串文字串联在一起.海湾合作委员会 3.4及更高版本将它们视为变量,例如__func__
.在C ++中,__FUNCTION__
和__PRETTY_FUNCTION__
始终是变量.
These identifiers are not preprocessor macros. In GCC 3.3 and earlier, in C only,
__FUNCTION__
and__PRETTY_FUNCTION__
were treated as string literals; they could be used to initialize char arrays, and they could be concatenated with other string literals. GCC 3.4 and later treat them as variables, like__func__
. In C++,__FUNCTION__
and__PRETTY_FUNCTION__
have always been variables.
有充分的理由说明为什么这些不能成为预处理器构造.预处理器不知道什么是函数,不知道它正在处理的文本是否在函数范围内,或者包围函数的名称是什么.它是一个简单的文本处理器,而不是编译器.显然,有可能在预处理器中建立起如此多的理解(仅是为了支持这一功能),但这不是标准所必需的,标准也不是必需的.
There are sound reasons why these cannot be preprocessor constructs. The preprocessor does not know what a function is and whether the text it is processing is in the scope of a function, or what the name of the enclosing function is. It is a simple text processor, not a compiler. Clearly, it would be possible to build that much understanding into the preprocessor (solely for the support of this one feature), but it is not required by the standard, and neither should it be required by the standard.
但是,不幸的是,我认为这意味着将__func__
(通过任何拼写方式)与__FILE__
和__LINE__
组合在单个宏中以生成单个字符串文字的尝试注定要失败.
Unfortunately, though, I think it means that attempts to combine __func__
(by any spelling) with __FILE__
and __LINE__
in a single macro to generate a single string literal are doomed.
很明显,您可以使用标准的两步宏机制将文件名和行号生成为字符串:
Clearly, you can generate the file name and line number as a string using the standard two-step macro mechanism:
#define STR(x) #x
#define STRINGIFY(x) STR(x)
#define FILE_LINE __FILE__ ":" STRINGIFY(__LINE__)
但是,您不能将函数名称作为字符串文字的一部分包含在其中.
You can't get the function name into that as part of a string literal, though.
有一些论据表明文件名和行号足以确定问题出在哪里;函数名称几乎没有必要.它比功能更美观,并且对程序员有一点帮助,但对其他用户没有帮助.
There are arguments that the file name and line number are sufficient to identify where the problem is; the function name is barely necessary. It is more cosmetic than functional, and slightly helps programmers but not other users.
这篇关于将__func__视为字符串文字而不是预定义的标识符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!