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

Lig*_*ica 18 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;
}
Run Code Online (Sandbox Code Playgroud)

两个站点都使用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
Run Code Online (Sandbox Code Playgroud)

ideone(顺便提一下,使用libc ++,Coliru的铿锵声3.5.0)

match1
match2
match3
Run Code Online (Sandbox Code Playgroud)

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

eca*_*mur 25

这是libstdc ++的regex_token_iterator拷贝构造函数中一个错误,由postincrement运算符调用.该错误已于2014年12月修复; 从那时起发布的gcc 4.9和5.x版本将有修复.错误的本质是迭代器的副本将副本的目标别名化,从而导致观察到的行为.

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

for (; it != end; ++it) std::cout << *it << std::endl;
Run Code Online (Sandbox Code Playgroud)


Lig*_*ica 9

代码有效.

唯一合理的解释是标准库版本不同; 虽然大多数情况下标准库实现随编译器一起提供,但它们可以通过Linux软件包管理器独立升级.

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

我可以找到Bugzilla上最可能匹配的是bug 63497但是,老实说,我不相信Bugzilla会完全覆盖这个特定的bug.约瑟夫曼斯菲尔德 发现,在这种特定情况下,这些特定症状至少是由修复后增量触发的.