为什么不同的GCC 4.9.2安装会为此正则表达式匹配提供不同的结果?

时间:2015-04-20 14:35:56

标签: c++ regex gcc c++14

我在ideoneColiru上发布了以下代码:

#include <iostream>
#include <regex>
#include <string>

int main() 
{
    std::string example{"   <match1>  <match2>    <match3>"};
    std::regex re{"<([^>]+)>"};
    std::regex_token_iterator<std::string::iterator> it{example.begin(), example.end(), re, 1};
    decltype(it) end{};
    while (it != end) std::cout << *it++ << std::endl;
    return 0;
}

两个站点都使用GCC 4.9.2。我不知道ideone使用的编译参数,但Coliru没有什么不寻常的。

Coliru没有给我match1结果:

Coliru

# g++ -v 2>&1 | grep version; \
# g++ -std=c++14 -O2 -Wall -pedantic -pthread main.cpp && ./a.out
gcc version 4.9.2 (GCC) 
match2
match3

ideone(顺便说一下,Coliru's clang 3.5.0 using libc++

match1
match2
match3

我的代码是否有未定义的行为?什么可能导致这种情况?

2 个答案:

答案 0 :(得分:25)

它是a bug in libstdc++'s regex_token_iterator copy constructor,由后增量运算符调用。该错误已于2014年12月修复;从那时起发布的gcc 4.9和5.x版本将有修复。错误的本质是迭代器的副本别名副本的目标,导致观察到的行为。

解决方法是使用preincrement - 从微观优化的角度来看这也是可取的,因为regex_token_iterator是一个相当重的类:

for (; it != end; ++it) std::cout << *it << std::endl;

答案 1 :(得分:9)

代码有效。

唯一合理的解释是标准库版本不同;虽然大多数标准库实现都附带编译器,但它们可以通过Linux包管理器独立升级。

在这个例子中,这似乎是去年年底修复的libstdc ++错误:

我可以找到的Bugzilla最可能的匹配是bug 63497但是,说实话,我不相信Bugzilla会完全覆盖这个特定的bug。 Joseph Mansfield identified these specific symptoms in this specific case are triggered by the post-fix increment,至少。{/ p>