mi sono imbattuto in un interessante regola sicura codifica in C++ in cui si afferma:C++ con un comportamento indefinito, compilatore genera std :: eccezione
Do not reenter a function during the initialization of a static variable declaration. If a function is reentered during the constant initialization of a static object inside that function, the behavior of the program is undefined. Infinite recursion is not required to trigger undefined behavior, the function need only recur once as part of the initialization.
L'esempio non_compliant dello stesso è:
#include <stdexcept>
int fact(int i) noexcept(false) {
if (i < 0) {
// Negative factorials are undefined.
throw std::domain_error("i must be >= 0");
}
static const int cache[] = {
fact(0), fact(1), fact(2), fact(3), fact(4), fact(5),
fact(6), fact(7), fact(8), fact(9), fact(10), fact(11),
fact(12), fact(13), fact(14), fact(15), fact(16)
};
if (i < (sizeof(cache)/sizeof(int))) {
return cache[i];
}
return i > 0 ? i * fact(i - 1) : 1;
}
che secondo la fonte dà l'errore:
terminate called after throwing an instance of '__gnu_cxx::recursive_init_error'
what(): std::exception
quando eseguito in Visual Studio 2013. Ho provato un codice simile e ho ottenuto lo stesso errore (compilato usando g ++ ed eseguito, su Ubuntu).
Sono dubbioso se la mia comprensione è corretta rispetto a questo concetto poiché non sono esperto di C++. Secondo me, dato che l'array di cache è costante, il che significa che può essere di sola lettura e deve essere inizializzato una sola volta come statico, viene inizializzato di nuovo e di nuovo poiché i valori di questo array sono il valore restituito da ciascuno dei chiamate di funzioni ricorsive separate da virgola contro il comportamento dell'array dichiarato. Quindi, dà un comportamento indefinito che è anche indicato nella regola.
Qual è una spiegazione migliore per questo?
Sto capendo correttamente: vuoi la ragione dipendente dall'implementazione perché questo determinato caso di comportamento indefinito si comporta in questo modo particolare? – Downvoter
@cad: hai ragione! .... :) –