简体   繁体   English

Visual Studio regex_iterator Bug?

[英]Visual Studio regex_iterator Bug?

I'm on Visual Studio 2013 and I'm seeing what I think is a bug, I was hoping someone could confirm? 我在使用Visual Studio 2013,我看到了我认为的错误,我希望有人可以证实?

string foo{ "A\nB\rC\n\r" };
vector<string> bar;

for (sregex_iterator i(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}")); i != sregex_iterator(); ++i){
    bar.push_back(i->operator[](1).str());
}

This code hits a Debug Assertion in the Visual Studio regex library: 此代码命中Visual Studio regex库中的Debug Assertion:

regex_iterator orphaned regex_iterator孤儿

If I define the regex outside the for -loop it's fine: 如果我在for -loop之外定义regex for那很好:

string foo{ "A\nB\rC\n\r" };
vector<string> bar;
regex bug("(.*)[\n\r]{1,2}");

for (sregex_iterator i(foo.cbegin(), foo.cend(), bug); i != sregex_iterator(); ++i){
    bar.push_back(i->operator[](1).str());
}

Alternatively this works fine in a transform as shown in this question : 或者,这可以在转换中正常工作, 如此问题所示:

string foo{ "A\nB\rC\n\r" };
vector<string> bar;

// This puts {"A", "B", "C"} into bar
transform(sregex_iterator(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}")), sregex_iterator(), back_inserter(bar), [](const smatch& i){ return i[1].str(); });

Can someone confirm this is a bug? 有人可以证实这是一个错误吗?

In C++11 you are allowed to bind a temporary regex to const regex & which can lead to undefined behavior if the iterator is used outside of the lifetime of the temporary since it will store a pointer to it. 在C ++ 11中,您可以将临时regex绑定到const regex &如果迭代器在临时生命周期之外使用, const regex &可能导致未定义的行为,因为它将存储指向它的指针。 This is a defect in the specification and it is not an error, although Visual Studio catches this with a debug assert. 这是规范中的缺陷,虽然Visual Studio通过调试断言捕获了它,但它并不是错误。

sregex_iterator i(foo.cbegin(), foo.cend(), regex("(.*)[\n\r]{1,2}"))
                                            ^^^^^
                                            temporary

The following deleted overload was adding in C++14 to prevent this case, from cppreference : 以下删除的重载是在C ++ 14中添加来防止这种情况,来自cppreference

regex_iterator(BidirIt, BidirIt,
           const regex_type&&,
           std::regex_constants::match_flag_type =
           std::regex_constants::match_default) = delete;       (since C++14)

and it says: 它说:

The overload 2 is not allowed to be called with a temporary regex, since the returned iterator would be immediately invalidated. 不允许使用临时正则表达式调用重载2,因为返回的迭代器将立即失效。

So this is not a Visual Studio bug since it is implementing the C++11 standard and this was not addressed via a defect report till later on. 因此,这不是Visual Studio错误,因为它正在实现C ++ 11标准,直到后来才通过缺陷报告解决。 Both clang and gcc using -std=c++14 or greater will produce an error with your first( see it live ) and third( see it live ) example. 使用-std=c++14或更高版本的clanggcc都会在您的第一个( 实时播放 )和第三个( 请参见实时 )示例中产生错误。 Visual Studio only started supporting some C++14 in VS 2015 : Visual Studio仅开始支持VS 2015中的一些C ++ 14:

[...]and initial support for certain C++14 features.[...] [...]并初步支持某些C ++ 14功能。[...]

We can see that LWG defect 2332: regex_iterator/regex_token_iterator should forbid temporary regexes deals with this: 我们可以看到LWG缺陷2332:regex_iterator / regex_token_iterator应该禁止临时正则表达式处理:

Users can write "for(sregex_iterator i(s.begin(), s.end(), regex("meow")), end; i != end; ++i)", binding a temporary regex to const regex& and storing a pointer to it. 用户可以写“for(sregex_iterator i(s.begin(),s.end(),regex(”meow“)),end; i!= end; ++ i)”,将临时正则表达式绑定到const regex&存储指向它的指针。 This will compile silently, triggering undefined behavior at runtime. 这将静默编译,在运行时触发未定义的行为。 We now have the technology to prevent this from compiling, like how reference_wrapper refuses to bind to temporaries. 我们现在有了防止这种编译的技术,就像reference_wrapper拒绝绑定到temporaries一样。

As TC points out the last example you show is actually ok, even though you are binding a temporary its lifetime extends to the end of the expression. 正如TC指出你显示的最后一个例子实际上是好的,即使你绑定一个临时的,它的生命周期延伸到表达式的结尾。

No, this is not a bug. 不,这不是一个错误。 See LWG 2329 regex_match()/regex_search() with match_results should forbid temporary strings . 请参阅LWG 2329 regex_match()/ regex_search(),match_results应禁止临时字符串 This construct exhibits undefined behavior since it binds a temporary regex to const regex& and stores a pointer to it. 此构造表现出未定义的行为,因为它将临时正则表达式绑定到const正则表达式并存储指向它的指针。

Also see C++14 STL Features, Fixes, And Breaking Changes In Visual Studio 14 CTP1 where this is listed as a fix. 另请参阅Visual Studio 14 CTP1中的C ++ 14 STL功能,修复和重大更改 ,其中列出了此修复程序。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM