Ho un problema simile quando uso un compilatore obsoleto (VisualDSP) su una piattaforma embedded che non supporta ancora C++ 11 (e quindi non posso usare constexpr).
Non ho bisogno di valutare la lunghezza della stringa nel precompilatore, ma ho bisogno di ottimizzarlo in un singolo compito.
Solo nel caso qualcuno ha bisogno di questo in futuro, ecco la mia soluzione estremamente hacky che dovrebbe funzionare su compilatori anche schifosi finchè lo fanno corretta ottimizzazione:
#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.
Questa macro STRLEN vi darà la lunghezza la stringa letterale che fornisci, purché sia lunga meno di 10 caratteri. Nel mio caso questo è sufficiente, ma nel caso degli OP la macro potrebbe dover essere estesa (molto). Dal momento che è altamente ripetitivo, è possibile scrivere facilmente uno script per creare una macro che accetta 1000 caratteri.
PS: Questa è solo una semplice derivazione del problema che stavo veramente cercando di risolvere, che è un valore HASH calcolato staticamente per una stringa, quindi non ho bisogno di usare alcuna stringa nel mio sistema embedded. Nel caso in cui qualcuno è interessato (mi avrebbe risparmiato un giorno di ricerca e risoluzione), questo farà un hash FNV su una piccola stringa letterale che può essere ottimizzato via in un unico compito:
#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"))
si potrebbe desiderare di assicuratevi che sia chiaro perché valuta a 5 e non a 4. –
sizeof ("blah") è 5. Ma il problema è che sizeof (blah) dove 'char * blah =" blah "' è 4 perché è una dimensione puntatore nel sistema a 32 bit. È un problema perché non abbiamo bisogno di sizeof ("stringa di cemento"). Abbiamo bisogno di sizeof (given_pointer). Dovrai usare strlen (pointer), ma è sux e la necessità di aggiungere +1 è un problema minore qui. – Val