为什么__func __,__ FUNCTION__和__PRETTY_FUNCTION__不是预处理器宏?

Pap*_*ter 28 c++ standards c-preprocessor

我刚刚注意到这一点__func__,__FUNCTION____PRETTY_FUNCTION__没有被视为预处理器宏,并且在标准(N4527工作草案)的16.8预定义宏名称部分中没有提到它们.

这意味着它们不能用于阶段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__}; }
Run Code Online (Sandbox Code Playgroud)

据我所知,__FILE__,__DATE__并且__TIME__被翻译成由标准规定字符串文字:

16.8预定义的宏名称[cpp.predefined]

__DATE__

源文件的转换日期:表单的字符串文字"Mmm dd yyyy",其中月份的名称与asctime函数生成的月份名称相同,如果值小于dd,则dd的第一个字符是空格字符10.如果没有翻译日期,则应提供实施定义的有效日期.

__FILE__

当前源文件的假定名称(字符串文字).

__TIME__

源文件的转换时间:表单的字符串文字,"hh:mm:ss"与asctime函数生成的时间一样.

__func__ 标准提到作为函数本地预定义变量的形式:

static const char __func__[] = "function-name ";
Run Code Online (Sandbox Code Playgroud)

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

至于__FUNCTION____PRETTY_FUNCTION__标准没有提及(是实现定义的?),但是是一个非常安全的赌注,认为他们会表现得像__func__.

所以问题是:为什么__func__,__FUNCTION__并且__PRETTY_FUNCTION__是函数本地静态常量字符数组__FILE__,__DATE__而且__TIME__是字符串文字?这个决定背后的理由是什么(如果有的话)?

小智 31

__func__在预处理时间扩展需要预处理器知道它正在处理哪个函数.预处理器通常不知道,因为解析在预处理器已经完成之后发生.

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