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__
这样的.然而,对于将翻译阶段分开的实现,这是一种不合理的要求.