使用-O1编译时,C ++ regex_search中断

FJD*_*JDU 7 c++ regex c++11 clang++

样例代码:

#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;
}
Run Code Online (Sandbox Code Playgroud)

当使用

g++ -std=c++11 main.cpp
Run Code Online (Sandbox Code Playgroud)

输出是

2 m.str(1): |10| 10
Run Code Online (Sandbox Code Playgroud)

这是预期的。

但是,当使用

g++ -std=c++11 -O1 main.cpp
Run Code Online (Sandbox Code Playgroud)

输出变为

libc++abi.dylib: terminating with uncaught exception
of type std::invalid_argument: stoi: no conversion
2 m.str(1): || Abort trap: 6
Run Code Online (Sandbox Code Playgroud)

编译器版本:

g++ -v
Run Code Online (Sandbox Code Playgroud)

配置为:--prefix = / Library / Developer / CommandLineTools / usr --with-gxx-include-dir = / Library / Developer / CommandLineTools / SDKs / MacOSX10.14.sdk / usr / include / c ++ / 4.2.1 Apple LLVM版本10.0.1(clang-1001.0.46.3)目标:x86_64-apple-darwin18.5.0线程模型:posix InstalledDir:/ Library / Developer / CommandLineTools / usr / bin

Fan*_*Fox 8

我对regex_search您在这里使用的重载的理解:

std::regex_search(std::string("10"), m, npat);
Run Code Online (Sandbox Code Playgroud)

是否具有签名:

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);
Run Code Online (Sandbox Code Playgroud)

请注意,它通过引用获取字符串。通过临时传递它,您正在调用未定义的行为。您可以在以下说明中看到这一点std::match_results

因为std :: match_results持有std :: sub_matches,每个std :: sub_matches都是一对匹配到原始字符序列的迭代器,所以检查std :: match_results是否是原始字符序列被破坏或对其迭代器无效的行为是不确定的由于其他原因。

从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;
Run Code Online (Sandbox Code Playgroud)

来自std::regex_search