将__func__视为字符串文字而不是预定义的标识符 [英] Treating __func__ as a string literal instead of a predefined identifier

查看:116
本文介绍了将__func__视为字符串文字而不是预定义的标识符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用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__?涵盖了一些替代名称.这些是特定于GCC的扩展名,而不是标准名称.此外,GCC 4.8.1文档说:

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆