为什么__func__,__FUNCTION__和__PRETTY_FUNCTION__不是预处理器宏? [英] Why __func__, __FUNCTION__ and __PRETTY_FUNCTION__ aren't preprocessor macros?
问题描述
我刚刚注意到 __ func __
, __ FUNCTION __
和 __ PRETTY_FUNCTION __
不被视为预处理器宏,并且在标准的 16.8预定义宏名称部分中未提及它们(N4527工作草案)。
I've just noticed that __func__
, __FUNCTION__
and __PRETTY_FUNCTION__
aren't treated as preprocessor macros and they're not mentioned on the 16.8 Predefined macro names section of the Standard (N4527 Working Draft).
这意味着它们不能用于阶段6 的字符串连接技巧:
This means that they cannot be used in the string concatenation trick of phase 6:
// Valid
constexpr char timestamp[]{__FILE__ " has been compiled: " __DATE__ " " __TIME__};
// Not valid!!!
template <typename T>
void die() { throw std::runtime_error{"Error detected in " __PRETTY_FUNCTION__}; }
据我所知, __ FILE __
, __ DATE __
和 __ TIME __
会按照标准说明转换为字符串文字:
As far as I know, the __FILE__
, __DATE__
and __TIME__
are translated to string literals as stated by the standard:
16.8预定义宏名[cpp.predefined]
__ DATE __
源文件的翻译日期:字符字符串文字,格式为 Mmm dd yyyy
,其中月份的名称与asctime函数生成的月份的名称相同,并且dd的第一个字符(如果值小于10)为空格字符。没有可用的
,则应提供实现定义的有效日期。
The date of translation of the source file: a character string literal of the form "Mmm dd yyyy"
, where the names of the months are the same as those generated by the asctime function, and the first character of dd is a space character if the value is less than 10. If the date of translation is not
available, an implementation-defined valid date shall be supplied.
__ FILE __
当前源文件的假定名称(字符字符串文字)。
The presumed name of the current source file (a character string literal).
__ TIME __
翻译的时间源文件:一个字符串字符串文字,格式为 hh:mm:ss
,与asctime函数生成的时间相同。
The time of translation of the source file: a character string literal of the form "hh:mm:ss"
as in the time generated by the asctime function.
__ func __
被标准称为函数本地的预定义变量,其形式为:
__func__
is mentioned by the standard as a function-local predefined variable of the form:
static const char __func__[] = "function-name ";
所以事实是这是一个局部变量,因此字符串连接技巧无法使用。
So the fact is that is a local variable hence the string concatenation trick doesn't works with it.
对于 __ FUNCTION __
和 __ PRETTY_FUNCTION __
没有提及在标准中(是否定义了实现?),但可以肯定地认为它们的行为类似于 __ func __
。
As for __FUNCTION__
and __PRETTY_FUNCTION__
aren't mentioned in the standard (are implementation defined?) but is a pretty safe bet to think that they would behave like __func__
.
所以问题是:为什么 __ func __
, __ FUNCTION __
和 __ PRETTY_FUNCTION __
是函数局部的静态常量字符数组,而 __ FILE __
, __ DATE __
和 __ TIME __
是字符串文字吗?这项决定的依据(如果有)是什么?
So the question is: Why __func__
, __FUNCTION__
and __PRETTY_FUNCTION__
are function-local static constant array of characters while __FILE__
, __DATE__
and __TIME__
are string literals? What's the rationale (if any) behind this decision?
推荐答案
扩展 __ func __
在预处理时,要求预处理器知道它正在处理哪个函数。预处理器通常不知道,因为解析是在预处理器完成之后进行的。
Expanding __func__
at preprocessing time requires the preprocessor to know which function it's processing. The preprocessor generally doesn't know that, because parsing happens after the preprocessor is already done.
某些实现将预处理和解析结合在一起,在这些实现中,它将 __ func __
可以按照您希望的方式工作。实际上,如果我没记错的话,MSVC的 __ FUNCTION __
就是这样。不过,对于将翻译的各个阶段分开的实施,这是不合理的要求。
Some implementations combine the preprocessing and the parsing, and in those implementations, it would have been possible for __func__
to work the way you'd like it to. In fact, if I recall correctly, MSVC's __FUNCTION__
works like that. It's an unreasonable demand on implementations that separate the phases of translation though.
这篇关于为什么__func__,__FUNCTION__和__PRETTY_FUNCTION__不是预处理器宏?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!