C++ 11 §28.6 stati
La classe regex_error
definisce il tipo di oggetti lanciati come eccezioni a segnalare errori dalla libreria di espressione regolare.
Ciò significa che la libreria <regex>
non deve generare altro da sola. È corretto che la costruzione di un regex_error
che eredita da runtime_error
possa generare bad_alloc
durante la costruzione a causa di condizioni di esaurimento della memoria, pertanto è necessario verificarlo nel codice di gestione degli errori. Sfortunatamente, ciò rende impossibile determinare quale costruzione di regex_error
lanci effettivamente bad_alloc
.
Per regolare algoritmi espressioni in §28.11 si afferma in §28.11.1 che
Gli algoritmi descritti in questa sottoclausola possono un'eccezione di tipo regex_error
. Se viene generata una tale eccezione e
, e.code()
deve restituire regex_constants::error_complexity
o regex_-constants::error_stack
.
Ciò significa che se le funzioni in §28.11 generano mai uno regex_error
, deve contenere uno di questi codici e nient'altro. Tuttavia, tieni presente che anche le cose che passi alla libreria <regex>
, come ad esempio gli allocatori ecc. Possono essere generate, ad es. l'allocatore di match_results
che potrebbe attivarsi se i risultati vengono aggiunti al contenitore match_results
specificato. Si noti inoltre che §28.11 ha funzioni abbreviate che "come se" costruiscono match_results
, come
template <class BidirectionalIterator, class charT, class traits>
bool regex_match(BidirectionalIterator first, BidirectionalIterator last,
const basic_regex<charT, traits> & e,
regex_constants::match_flag_type flags =
regex_constants::match_default);
template <class BidirectionalIterator, class charT, class traits>
bool regex_search(BidirectionalIterator first, BidirectionalIterator last,
const basic_regex<charT, traits> & e,
regex_constants::match_flag_type flags =
regex_constants::match_default);
e possibilmente altri. Dal momento che tale potrebbe costruire e utilizzare match_results
con lo standard allocator
internamente, è possibile che vengano lanciati lanci di qualsiasi cosa. Pertanto il tuo semplice esempio di regex_match(anyString, regex("."))
potrebbe anche essere generato a causa della costruzione e dell'utilizzo dell'allocatore predefinito.
altro avvertimento da notare che per alcuni <regex>
funzioni e classi è attualmente impossibile determinare se un bad_alloc
generato dal alcuni allocatore o durante la costruzione di un'eccezione regex_error
.
In generale, se avete bisogno di qualcosa con specifiche migliori, evitate di usare <regex>
. Se si richiede una semplice corrispondenza di modelli, è meglio ruotare le proprie funzioni di corrispondenza/ricerca/sostituzione sicure, poiché è impossibile limitare le espressioni regolari per evitare tali eccezioni in un modo portatile o compatibile con i contratti di trasporto, anche utilizzando un'espressione regolare vuota ""
potrebbe darti un'eccezione.
PS: Si noti che lo standard C++ 11 è scritto piuttosto male in alcuni aspetti, mancando di riferimenti incrociati completi. Per esempio. non c'è alcun avviso esplicito sotto le clausole per i metodi di match_results
per lanciare qualsiasi cosa, mentre §28.10.1.1 stati (sottolineatura mia):
In tutti match_results
costruttori, una copia della tesi Allocator
devono essere utilizzati per qualsiasi memoria l'allocazione eseguita dalle funzioni del costruttore o membro durante il ciclo di vita dell'oggetto.
Quindi fai attenzione quando leggi gli standard come un avvocato! ;-)
C'è l'ovvio ['regex_error'] (http://en.cppreference.com/w/cpp/regex/regex_error) – MSalters
Ehi amico, non penso che riuscirai a muoverti gestione delle eccezioni per le funzioni di ricerca/corrispondenza/sostituzione. Per la compilazione probabilmente lo puoi fare. Sto usando e assumendo la gestione delle eccezioni di Boost :: Regex come guida perché, diciamocelo, la regex di C++ 11 è originata dal motore boost :: regex. La visualizzazione del codice boost è più facile da decifrare. Se non gestisci le eccezioni generate, il sistema operativo lo gestirà. Se pensi che la definizione di _noexcept_ (ovvero: BOOST_NO_EXCEPTIONS) interromperà i lanci di runtime durante l'esecuzione della loro implementazione, ti sbaglieresti. – sln
(con't) L'eccezione principale di queste funzioni è _ran_out_of_stack_ durante la ricorsione interna. Anche l'impostazione dell'equivalente BOOST_REGEX_NON_RECURSIVE (il modo più sicuro, ma più lento) potrebbe ancora generare un lancio. È meglio catturare questi dati piuttosto che ottenere un messaggio oscuro del sistema. In profondità nelle viscere di trovare/abbinare/sostituire è il _imp_ di queste funzioni che possono _catch_ e ripensare tutto. L'eccezione può provenire dal sistema operativo o da qualsiasi luogo. Anche la cattura non garantisce che il thread non si blocchi a causa della ricorsione infinita. – sln