c++ gcc c++17 constexpr

c++ - gcc g++



¿Por qué estas dos piezas de código que utilizan constexpr,__PRETTY_FUNCTION__ y char*tienen resultados diferentes? (1)

De hecho, este es un error en GCC, como se comentó en los comentarios, pero pensé que podría aportar alguna información adicional sobre la naturaleza de este error. En el archivo GCC NEWS hay esta línea:

  • __FUNCTION__ y __PRETTY_FUNCTION__ ahora son tratadas como variables por el analizador; Anteriormente eran tratados como constantes de cuerdas. Por lo tanto, el código como printf (__FUNCTION__ ": foo") debe reescribir en printf ("%s: foo", __FUNCTION__) . Esto es necesario para las plantillas.

Pero __PRETTY_FUNCTION__ no es realmente una variable, es un caso especial tratado en el analizador como vemos en constexpr.c :

case DECL_EXPR: { tree decl = DECL_EXPR_DECL (body); if (TREE_CODE (decl) == USING_DECL /* Accept __func__, __FUNCTION__, and __PRETTY_FUNCTION__. */ || DECL_ARTIFICIAL (decl)) return NULL_TREE; return error_mark_node; }

Si realmente fuera una variable, esperaríamos que pasara los mismos casos de prueba que estos:

constexpr const char* s2 = "TEST"; constexpr const char* s3 = s2; test_template<ce_strlen("TEST")> c; test_template<ce_strlen(s2)> d; test_template<ce_strlen(s3)> e;

Tengo este código donde, si comentas, la línea comentó "¿ Pero esto no funciona? ", Se compila bien, pero si no lo haces, el compilador genera un error.

Al menos, gcc 8.2 genera un error .

Pero, me parecen idénticos. ¿Cuál es el problema? ¿Es este código legal en absoluto?

template <int x> struct test_template { static int size() { return x; } }; constexpr int ce_strlen(char const *s) { int i = 0; while (s[i]) ++i; return i; } int joe() { constexpr int plen = ce_strlen(__PRETTY_FUNCTION__); // This works test_template<plen> a; // This declaration is valid. test_template<ce_strlen(__PRETTY_FUNCTION__)> b; // But this doesn''t work?! return a.size() + b.size(); }

Me encontré con esto mientras trataba de encontrar una manera de crear etiquetas de perfil para un sistema de perfiles intrusivo en tiempo de compilación . Lo logré, pero mi código final no implica el uso de ce_strlen .