Simple std::regex_search() code won't compile with Apple clang++ -std=c++14

后端 未结 3 677
-上瘾入骨i
-上瘾入骨i 2020-12-07 01:23

Here is the MCVE:

#include 
#include 

std::string s()
{
    return \"test\";
}

int main()
{
    static const std::regex regex(         


        
3条回答
  •  情书的邮戳
    2020-12-07 01:39

    This changed between C++11 and C++14. If we go to the cppreference section for std::regex_search we can see that overload that takes an rvalue reference was deleted since C++14:

    template< class STraits, class SAlloc,
              class Alloc, class CharT, class Traits > bool regex_search( const std::basic_string&&,
                       std::match_results<
                           typename std::basic_string::const_iterator,
                           Alloc
                       >&,
                       const std::basic_regex&,
                       std::regex_constants::match_flag_type flags =
                           std::regex_constants::match_default ) = delete;
    

    It was changed due to LWG issue 2329: regex_match()/regex_search() with match_results should forbid temporary strings which says (emphasis mine):

    Consider the following code:

    const regex r(R"(meow(\d+)\.txt)");
    smatch m;
    if (regex_match(dir_iter->path().filename().string(), m, r)) {
      DoSomethingWith(m[1]);
    }
    

    This occasionally crashes. The problem is that dir_iter->path().filename().string() returns a temporary string, so the match_results contains invalidated iterators into a destroyed temporary string.

    It's fine for regex_match/regex_search(str, reg) to accept temporary strings, because they just return bool. However, the overloads taking match_results should forbid temporary strings.

    and indeed if we use a non-temporary:

    std::string s1 = s() ;
    
    if (std::regex_search(s1, smatch, regex)) {
    //...
    }
    

    it compiles (see it live) and no longer exhibits undefined behavior.

    Interesting to note that gcc/libstdc++ has this overload deleted in C++11 mode as well see it live. Since this is undefined behavior it seems like a good solution.

    This issue also pops up in other areas of the library see Visual Studio regex_iterator Bug? which deals with the same issue but with regex_iterator/regex_token_iterator.

提交回复
热议问题