From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 48) id 086643858C5E; Mon, 5 Feb 2024 10:55:29 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 086643858C5E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1707130529; bh=ToX07P+/gMkZ8VsNSp9QsQJpx0NUdwT9I4EbEq/baEE=; h=From:To:Subject:Date:In-Reply-To:References:From; b=E5UEGV1JTusQB4X4Nl+CbTMVgKQIhAXRA84KWd63Tt/e73+fNWZZy/uLqQMpsPOXK LYZ8bC+rHCs53jAqg80hE0wqclmmM8u3sp87Jo5Umgz3puuhZLTMrDBhaX+Cb5znen 15fR8b3ny1iFXTxs4nmcP/ecX7iXdvGMhQEBVxG8= From: "redi at gcc dot gnu.org" To: gcc-bugs@gcc.gnu.org Subject: [Bug libstdc++/113761] piecewise_constant_distribution's initializer_list constructor is not correct for `size < 2` Date: Mon, 05 Feb 2024 10:55:28 +0000 X-Bugzilla-Reason: CC X-Bugzilla-Type: changed X-Bugzilla-Watch-Reason: None X-Bugzilla-Product: gcc X-Bugzilla-Component: libstdc++ X-Bugzilla-Version: 12.3.0 X-Bugzilla-Keywords: X-Bugzilla-Severity: normal X-Bugzilla-Who: redi at gcc dot gnu.org X-Bugzilla-Status: NEW X-Bugzilla-Resolution: X-Bugzilla-Priority: P3 X-Bugzilla-Assigned-To: unassigned at gcc dot gnu.org X-Bugzilla-Target-Milestone: --- X-Bugzilla-Flags: X-Bugzilla-Changed-Fields: Message-ID: In-Reply-To: References: Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable X-Bugzilla-URL: http://gcc.gnu.org/bugzilla/ Auto-Submitted: auto-generated MIME-Version: 1.0 List-Id: https://gcc.gnu.org/bugzilla/show_bug.cgi?id=3D113761 --- Comment #4 from Jonathan Wakely --- (In reply to Andrew Pinski from comment #2) > It seems like libstdc++ miss that part, I wonder if it changed ... No, it didn't change. We've just always had that bug. Well, not quite alway= s, looks like it was a regression in r0-94140-gf8dd9e0de06aef which added the reserve call. It's easy enough to fix: --- a/libstdc++-v3/include/bits/random.tcc +++ b/libstdc++-v3/include/bits/random.tcc @@ -2877,10 +2877,10 @@ namespace __detail param_type(initializer_list<_RealType> __bl, _Func __fw) : _M_int(), _M_den(), _M_cp() { - _M_int.reserve(__bl.size()); - for (auto __biter =3D __bl.begin(); __biter !=3D __bl.end(); ++__bi= ter) - _M_int.push_back(*__biter); + if (__bl.size() < 2) + return; + _M_int =3D __bl; _M_den.reserve(_M_int.size() - 1); for (size_t __k =3D 0; __k < _M_int.size() - 1; ++__k) _M_den.push_back(__fw(0.5 * (_M_int[__k + 1] + _M_int[__k]))); But I don't understand why piecewise_constant_distribution is implemented t= his way: template void piecewise_constant_distribution<_RealType>::param_type:: _M_initialize() { if (_M_int.size() < 2 || (_M_int.size() =3D=3D 2 && _M_int[0] =3D=3D _RealType(0) && _M_int[1] =3D=3D _RealType(1))) { _M_int.clear(); _M_den.clear(); return; } And then: std::vector<_RealType> intervals() const { if (_M_int.empty()) { std::vector<_RealType> __tmp(2); __tmp[1] =3D _RealType(1); return __tmp; } else return _M_int; } std::vector densities() const { return _M_den.empty() ? std::vector(1, 1.0) : _M_den; } This seems incredibly wasteful, why keep reallocating a new vector instead = of just populating _M_int with {1} and _M_den with {0,1}? Paolo did that in r0-103705-g879b9073c87cea and it makes no sense to me, I'll see if the mail= ing list has any clues. Also, we're missing https://cplusplus.github.io/LWG/issue1439 which fixed t= he return type of densities()=