c++ c-preprocessor standards

c++ - ¿Por qué__func__,__FUNCTION__ y__PRETTY_FUNCTION__ no son macros preprocesadoras?



c-preprocessor standards (1)

Expandir __func__ en el tiempo de preprocesamiento requiere que el preprocesador sepa qué función está procesando. El preprocesador generalmente no lo sabe, porque el análisis ocurre después de que el preprocesador ya está hecho.

Algunas implementaciones combinan el preprocesamiento y el análisis, y en esas implementaciones, habría sido posible para __func__ trabajar de la manera que le gustaría. De hecho, si recuerdo bien, __FUNCTION__ de __FUNCTION__ funciona así. Sin embargo, es una demanda irrazonable de implementaciones que separan las fases de traducción.

Acabo de notar que __func__ , __FUNCTION__ y __PRETTY_FUNCTION__ no se tratan como macros de preprocesador y no se mencionan en la sección 16.8 Nombres de macro predefinidos de la Norma ( borrador de trabajo N4527 ).

Esto significa que no se pueden utilizar en el truco de concatenación de cadenas de la fase 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__}; }

Por lo que sé, el __FILE__ , __DATE__ y __TIME__ se traducen a cadenas literales como lo establece la norma:

16.8 Nombres de macro predefinidos [cpp.predefined]

__DATE__

La fecha de traducción del archivo de origen: una cadena de caracteres literal de la forma "Mmm dd yyyy" , donde los nombres de los meses son los mismos que los generados por la función asctime, y el primer carácter de dd es un carácter de espacio si el valor es menor que 10. Si la fecha de traducción no está disponible, se proporcionará una fecha válida definida por la implementación.

__FILE__

El nombre presunto del archivo fuente actual (un literal de cadena de caracteres ).

__TIME__

El tiempo de traducción del archivo fuente: una cadena de caracteres literal de la forma "hh:mm:ss" como en el tiempo generado por la función asctime.

__func__ es mencionado por el estándar como una variable predefinida de función local de la forma:

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

Entonces, el hecho es que es una variable local, por lo que el truco de concatenación de cadenas no funciona con ella.

En cuanto a __FUNCTION__ y __PRETTY_FUNCTION__ no se mencionan en el estándar (¿se define la implementación?), Pero es una apuesta bastante segura pensar que se comportarían como __func__ .

Entonces, la pregunta es: ¿ __func__ qué __func__ , __FUNCTION__ y __PRETTY_FUNCTION__ son una matriz constante de caracteres de función constante local mientras que __FILE__ , __DATE__ y __TIME__ son literales de cadena? ¿Cuál es la razón (si existe) detrás de esta decisión?