Il problema si presenta a causa dei molteplici costruttori disponibili per std::regex
. Tracing nel costruttore l'ho mostrato usando uno che non intendevo!
ho voluto usare questo:
explicit basic_regex(_In_z_ const _Elem *_Ptr,
flag_type _Flags = regex_constants::ECMAScript)
ma ho avuto questa invece:
basic_regex(_In_reads_(_Count) const _Elem *_Ptr, size_t _Count,
flag_type _Flags = regex_constants::ECMAScript)
L'espressione ternaria nelle bandiere fa sì che il tipo di cambiare a int
, le partite che non è più flag_type
nella firma del costruttore. Dal momento che lo corrisponde a corrisponde a size_t
, chiama invece il costruttore. I flag vengono erroneamente interpretati come la dimensione della stringa, con conseguente comportamento non definito quando si accede alla memoria oltre la fine della stringa.
Il problema non è specifico di Visual Studio. Sono stato in grado di duplicarlo in gcc: http://ideone.com/5DjYiz
Può essere risolto in due modi. In primo luogo è un cast esplicito dell'argomento:
std::regex re(pattern, static_cast<std::regex::flag_type>(std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)));
In secondo luogo è quello di evitare costanti intere nell'espressione ternario:
std::regex re(pattern, caseInsensitive ? std::regex_constants::ECMAScript | std::regex_constants::icase : std::regex_constants::ECMAScript);
fonte
2016-01-07 20:30:36
La tua soluzione è sicuramente più leggibile, grazie. –