Tengo un problema similar cuando uso un compilador desactualizado (VisualDSP) en una plataforma incrustada que aún no es compatible con C++ 11 (y por lo tanto no puedo usar constexpr).
No necesito evaluar la longitud de la cadena en el precompilador, pero sí necesito optimizarla en una única tarea.
Por si alguien lo necesita en el futuro, aquí está mi solución extremadamente hacky que deben trabajar en compiladores incluso cutres, siempre y cuando lo hacen optimización adecuada:
#define STRLENS(a,i) !a[i] ? i : // repetitive stuff
#define STRLENPADDED(a) (STRLENS(a,0) STRLENS(a,1) STRLENS(a,2) STRLENS(a,3) STRLENS(a,4) STRLENS(a,5) STRLENS(a,6) STRLENS(a,7) STRLENS(a,8) STRLENS(a,9) -1)
#define STRLEN(a) STRLENPADDED((a "\0\0\0\0\0\0\0\0\0")) // padding required to prevent 'index out of range' issues.
Esta macro STRLEN le dará la longitud de el literal de cadena que usted le proporciona, siempre que tenga menos de 10 caracteres. En mi caso, esto es suficiente, pero en el caso de OPs, la macro puede necesitar ser extendida (mucho). Como es muy repetitivo, puede escribir fácilmente un script para crear una macro que acepte 1000 caracteres.
PD: Esto es solo una derivación simple del problema que realmente estaba tratando de solucionar, que es un valor HASH estáticamente calculado para una cadena, así que no necesito usar ninguna cadena en mi sistema integrado. En caso de que a alguien le interesa (que me habría ahorrado un día de búsqueda y resolución), esto va a hacer un hash FNV en una pequeña cadena literal que puede ser optimizado de distancia en una sola misión:
#ifdef _MSC_BUILD
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5ULL
#define HASH_TYPE int
#else // properly define for your own compiler to get rid of overflow warnings
#define HASH_FNV_OFFSET_BASIS 0x811c9dc5UL
#define HASH_TYPE int
#endif
#define HASH_FNV_PRIME 16777619
#define HASH0(a) (a[0] ? ((HASH_TYPE)(HASH_FNV_OFFSET_BASIS * HASH_FNV_PRIME)^(HASH_TYPE)a[0]) : HASH_FNV_OFFSET_BASIS)
#define HASH2(a,i,b) ((b * (a[i] ? HASH_FNV_PRIME : 1))^(HASH_TYPE)(a[i] ? a[i] : 0))
#define HASHPADDED(a) HASH2(a,9,HASH2(a,8,HASH2(a,7,HASH2(a,6,HASH2(a,5,HASH2(a,4,HASH2(a,3,HASH2(a,2,HASH2(a,1,HASH0(a))))))))))
#define HASH(a) HASHPADDED((a "\0\0\0\0\0\0\0\0\0"))
Es posible que desee asegúrese de que está claro por qué evalúa 5 y no 4. –
sizeof ("bla") es 5. Pero el problema es que sizeof (bla) donde 'char * bla =" blah "' es 4 porque es un tamaño de puntero en el sistema de 32 bits. Es un problema porque no necesitamos sizeof ("cuerda de hormigón"). Necesitamos sizeof (given_pointer). En su lugar, tendrá que usar strlen (puntero) pero es sux y la necesidad de agregar +1 es un problema menor aquí. – Val