为什么 __func__、__FUNCTION__ 和 __PRETTY_FUNCTION__ 不是预处理器宏?

Why __func__, __FUNCTION__ and __PRETTY_FUNCTION__ aren't preprocessor macros?

我刚刚注意到 __func____FUNCTION____PRETTY_FUNCTION__ 未被视为预处理器宏,并且未在 16.8 预定义中提及宏名称 标准部分 (N4527 Working Draft).

这意味着它们不能用于 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__ 被转换为标准规定的字符串文字:

16.8 Predefined macro names [cpp.predefined]

__DATE__

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__

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__ 被标准提及为形式为函数局部预定义变量:

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

所以事实是这是一个局部变量,因此字符串连接技巧不适用于它。

至于 __FUNCTION____PRETTY_FUNCTION__ 没有在标准中提及(是否定义了实现?)但是可以肯定的是,认为它们的行为会像 __func__

所以问题是:为什么__func____FUNCTION____PRETTY_FUNCTION__是函数局部静态常量字符数组,而__FILE____DATE____TIME__ 是字符串文字吗?这个决定背后的理由是什么(如果有的话)?

在预处理时扩展 __func__ 需要预处理器知道它正在处理哪个函数。预处理器通常不知道这一点,因为解析是在预处理器完成后发生的。

一些实现结合了预处理和解析,在这些实现中,__func__ 可以按照您希望的方式工作。事实上,如果我没记错的话,MSVC 的 __FUNCTION__ 就是这样工作的。但是,对将翻译阶段分开的实现的要求是不合理的。