简体   繁体   中英

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

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 ).

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__}; }

As far as I know, the __FILE__ , __DATE__ and __TIME__ are translated to string literals as stated by the standard:

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__ 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.

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__ .

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?

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.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM