Problem powstaje z powodu wielu konstruktorów dostępnych dla std::regex
. Śledzenie w konstruktorze pokazało to za pomocą jednego, którego nie zamierzałem!
chciałem użyć tego:
explicit basic_regex(_In_z_ const _Elem *_Ptr,
flag_type _Flags = regex_constants::ECMAScript)
Ale mam ten jeden Zamiast:
basic_regex(_In_reads_(_Count) const _Elem *_Ptr, size_t _Count,
flag_type _Flags = regex_constants::ECMAScript)
Trójskładnikowy wyraz w flagi powoduje typ, aby zmienić int
, która nie jest zgodna flag_type
w podpisie konstruktora. Ponieważ ma dopasowanie na size_t
, wywołuje ten konstruktor zamiast. Flagi są źle interpretowane jako rozmiar ciągu, powodując niezdefiniowane zachowanie, gdy dostęp do pamięci za końcem łańcucha jest możliwy.
Problem nie dotyczy tylko programu Visual Studio. Udało mi się zduplikować go w gcc: http://ideone.com/5DjYiz
Można go naprawić na dwa sposoby. Pierwszy z nich to wyraźne obsada argumentu:
std::regex re(pattern, static_cast<std::regex::flag_type>(std::regex_constants::ECMAScript | (caseInsensitive ? std::regex_constants::icase : 0)));
drugie jest uniknięcie stałych całkowitych w trójskładnikowych wyrażenie:
std::regex re(pattern, caseInsensitive ? std::regex_constants::ECMAScript | std::regex_constants::icase : std::regex_constants::ECMAScript);
Twoje rozwiązanie jest zdecydowanie bardziej czytelne, dzięki. –