为什么__func__,__FUNCTION__和__PRETTY_FUNCTION__不是预处理器宏? [英] Why __func__, __FUNCTION__ and __PRETTY_FUNCTION__ aren't preprocessor macros?

查看:197
本文介绍了为什么__func__,__FUNCTION__和__PRETTY_FUNCTION__不是预处理器宏?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我刚刚注意到 __ 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屋!

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