使用 -O1 编译时 C++ regex_search 中断
C++ regex_search breaks when compiled with -O1
示例代码:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::regex npat(R"(^(\d+))");
std::smatch m;
std::regex_search(std::string("10"), m, npat);
std::cout << m.size() << " m.str(1): |"
<< m.str(1) << "| ";
std::cout << std::stoi(m.str(1)) << std::endl;
}
编译时
g++ -std=c++11 main.cpp
输出是
2 m.str(1): |10| 10
这是预期的。
然而,编译时使用
g++ -std=c++11 -O1 main.cpp
输出变为
libc++abi.dylib: terminating with uncaught exception
of type std::invalid_argument: stoi: no conversion
2 m.str(1): || Abort trap: 6
编译器版本:
g++ -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr
--with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1
Apple LLVM version 10.0.1 (clang-1001.0.46.3) Target:
x86_64-apple-darwin18.5.0 Thread model: posix InstalledDir:
/Library/Developer/CommandLineTools/usr/bin
我对您在此处使用的 regex_search
重载的理解:
std::regex_search(std::string("10"), m, npat);
是否有签名:
template< class STraits, class SAlloc,
class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags);
请注意,它通过引用获取字符串。通过临时传递它,您正在调用未定义的行为。您可以在 std::match_results
:
的解释中看到这一点
Because std::match_results holds std::sub_matches, each of which is a pair of iterators into the original character sequence that was matched, it's undefined behavior to examine std::match_results if the original character sequence was destroyed or iterators to it were invalidated for other reasons.
从 c++14 开始,通过删除采用右值引用的运算符不允许此行为:
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>&,
const std::basic_regex<CharT, Traits>&,
std::regex_constants::match_flag_type flags) = delete;
示例代码:
#include <iostream>
#include <string>
#include <regex>
int main()
{
std::regex npat(R"(^(\d+))");
std::smatch m;
std::regex_search(std::string("10"), m, npat);
std::cout << m.size() << " m.str(1): |"
<< m.str(1) << "| ";
std::cout << std::stoi(m.str(1)) << std::endl;
}
编译时
g++ -std=c++11 main.cpp
输出是
2 m.str(1): |10| 10
这是预期的。
然而,编译时使用
g++ -std=c++11 -O1 main.cpp
输出变为
libc++abi.dylib: terminating with uncaught exception
of type std::invalid_argument: stoi: no conversion
2 m.str(1): || Abort trap: 6
编译器版本:
g++ -v
Configured with: --prefix=/Library/Developer/CommandLineTools/usr --with-gxx-include-dir=/Library/Developer/CommandLineTools/SDKs/MacOSX10.14.sdk/usr/include/c++/4.2.1 Apple LLVM version 10.0.1 (clang-1001.0.46.3) Target: x86_64-apple-darwin18.5.0 Thread model: posix InstalledDir: /Library/Developer/CommandLineTools/usr/bin
我对您在此处使用的 regex_search
重载的理解:
std::regex_search(std::string("10"), m, npat);
是否有签名:
template< class STraits, class SAlloc,
class CharT, class Traits >
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>& s,
const std::basic_regex<CharT,Traits>& e,
std::regex_constants::match_flag_type flags);
请注意,它通过引用获取字符串。通过临时传递它,您正在调用未定义的行为。您可以在 std::match_results
:
Because std::match_results holds std::sub_matches, each of which is a pair of iterators into the original character sequence that was matched, it's undefined behavior to examine std::match_results if the original character sequence was destroyed or iterators to it were invalidated for other reasons.
从 c++14 开始,通过删除采用右值引用的运算符不允许此行为:
bool regex_search( const std::basic_string<CharT,STraits,SAlloc>&&,
std::match_results<
typename std::basic_string<CharT,STraits,SAlloc>::const_iterator,
Alloc
>&,
const std::basic_regex<CharT, Traits>&,
std::regex_constants::match_flag_type flags) = delete;