Topic: std::regex ctor improvements.
Author: Dawid Kurek <dawikur@gmail.com>
Date: Wed, 24 Feb 2016 05:56:27 -0800 (PST)
Raw View
------=_Part_12450_1584926091.1456322187985
Content-Type: multipart/alternative;
boundary="----=_Part_12451_372209307.1456322187986"
------=_Part_12451_372209307.1456322187986
Content-Type: text/plain; charset=UTF-8
I had just watched Scott Mayers talk (https://youtu.be/smqT9Io_bKo). Around
0:50 he mentions issue with initializing i.e. std::vector<std::regex>. In
short:
std::vector<std::regex> rs;
rs.push_back(nullptr); // does not compile, fine
rs.emplace_back(nullptr); // compiles, which gives issue.
It compiles as we use direct initialization via basic_regex(const charT* p,
size_t len, flag_type f) ctor.
From standard n4567:
> explicit basic_regex(const charT* p, flag_type f =
> regex_constants::ECMAScript);
> Requires: p shall not be a null pointer.
My idea is to add explicitly deleted overloaded ctors:
explicit basic_regex(std::nullptr_t, flag_type f = regex_constants::
ECMAScript) = delete;
basic_regex(const charT* p, size_t len, flag_type f) = delete;
So cases with nullptr would be caught at compile time.
I have checked this with clang++3.7.
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/33981a62-eba4-4a31-a9ae-4d89ca671667%40isocpp.org.
------=_Part_12451_372209307.1456322187986
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">I had just watched Scott Mayers talk (https://youtu.be/smq=
T9Io_bKo). Around 0:50 he mentions issue with initializing i.e. std::vector=
<std::regex>. In short:<div><br></div><div class=3D"prettyprint" styl=
e=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; backgroun=
d-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"sub=
prettyprint"><span style=3D"color: #000;" class=3D"styled-by-prettify">std<=
/span><span style=3D"color: #660;" class=3D"styled-by-prettify">::</span><s=
pan style=3D"color: #000;" class=3D"styled-by-prettify">vector</span><span =
style=3D"color: #660;" class=3D"styled-by-prettify"><</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">std</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #000=
;" class=3D"styled-by-prettify">regex</span><span style=3D"color: #660;" cl=
ass=3D"styled-by-prettify">></span><span style=3D"color: #000;" class=3D=
"styled-by-prettify"> rs</span><span style=3D"color: #660;" class=3D"styled=
-by-prettify">;</span><span style=3D"color: #000;" class=3D"styled-by-prett=
ify"><br><br><br>rs</span><span style=3D"color: #660;" class=3D"styled-by-p=
rettify">.</span><span style=3D"color: #000;" class=3D"styled-by-prettify">=
push_back</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(=
</span><span style=3D"color: #008;" class=3D"styled-by-prettify">nullptr</s=
pan><span style=3D"color: #660;" class=3D"styled-by-prettify">);</span><spa=
n style=3D"color: #000;" class=3D"styled-by-prettify"> </span><span style=
=3D"color: #800;" class=3D"styled-by-prettify">// does not compile, fine</s=
pan><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>rs</span>=
<span style=3D"color: #660;" class=3D"styled-by-prettify">.</span><span sty=
le=3D"color: #000;" class=3D"styled-by-prettify">emplace_back</span><span s=
tyle=3D"color: #660;" class=3D"styled-by-prettify">(</span><span style=3D"c=
olor: #008;" class=3D"styled-by-prettify">nullptr</span><span style=3D"colo=
r: #660;" class=3D"styled-by-prettify">);</span><span style=3D"color: #000;=
" class=3D"styled-by-prettify"> </span><span style=3D"color: #800;" class=
=3D"styled-by-prettify">// compiles, which gives issue.</span></div></code>=
</div><div><br><div><font face=3D"courier new, monospace"><br></font></div>=
<div><font face=3D"arial, sans-serif">It compiles as we use direct initiali=
zation via=C2=A0</font><font face=3D"courier new, monospace">basic_regex(co=
nst charT* p, size_t len, flag_type f)</font><font face=3D"arial, sans-seri=
f">=C2=A0ctor.=C2=A0</font></div><div><span style=3D"font-family: arial, sa=
ns-serif;"><br></span></div><div><span style=3D"font-family: arial, sans-se=
rif;">From standard n4567:</span></div></div><blockquote class=3D"gmail_quo=
te" style=3D"margin: 0px 0px 0px 0.8ex; border-left-width: 1px; border-left=
-color: rgb(204, 204, 204); border-left-style: solid; padding-left: 1ex;"><=
font face=3D"arial, sans-serif">explicit basic_regex(const charT* p, flag_t=
ype f =3D regex_constants::ECMAScript);</font><br><font face=3D"arial, sans=
-serif">Requires: p shall not be a null pointer.</font></blockquote><div><f=
ont face=3D"arial, sans-serif"><br></font></div><div><font face=3D"courier =
new, monospace"><br></font></div><div><font face=3D"arial, sans-serif">My i=
dea is to add explicitly deleted overloaded ctors:</font></div><div><font f=
ace=3D"arial, sans-serif"><br></font></div><div class=3D"prettyprint" style=
=3D"border: 1px solid rgb(187, 187, 187); word-wrap: break-word; background=
-color: rgb(250, 250, 250);"><code class=3D"prettyprint"><div class=3D"subp=
rettyprint"><span style=3D"color: #008;" class=3D"styled-by-prettify">expli=
cit</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> basic_=
regex</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify">std</span><spa=
n style=3D"color: #660;" class=3D"styled-by-prettify">::</span><span style=
=3D"color: #000;" class=3D"styled-by-prettify">nullptr_t</span><span style=
=3D"color: #660;" class=3D"styled-by-prettify">,</span><span style=3D"color=
: #000;" class=3D"styled-by-prettify"> flag_type f </span><span style=3D"co=
lor: #660;" class=3D"styled-by-prettify">=3D</span><span style=3D"color: #0=
00;" class=3D"styled-by-prettify"> regex_constants</span><span style=3D"col=
or: #660;" class=3D"styled-by-prettify">::</span><span style=3D"color: #606=
;" class=3D"styled-by-prettify">ECMAScript</span><span style=3D"color: #660=
;" class=3D"styled-by-prettify">)</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> </span><span style=3D"color: #660;" class=3D"style=
d-by-prettify">=3D</span><span style=3D"color: #000;" class=3D"styled-by-pr=
ettify"> </span><span style=3D"color: #008;" class=3D"styled-by-prettify">d=
elete</span><span style=3D"color: #660;" class=3D"styled-by-prettify">;</sp=
an><span style=3D"color: #000;" class=3D"styled-by-prettify"><br>basic_rege=
x</span><span style=3D"color: #660;" class=3D"styled-by-prettify">(</span><=
span style=3D"color: #008;" class=3D"styled-by-prettify">const</span><span =
style=3D"color: #000;" class=3D"styled-by-prettify"> charT</span><span styl=
e=3D"color: #660;" class=3D"styled-by-prettify">*</span><span style=3D"colo=
r: #000;" class=3D"styled-by-prettify"> p</span><span style=3D"color: #660;=
" class=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=
=3D"styled-by-prettify"> size_t len</span><span style=3D"color: #660;" clas=
s=3D"styled-by-prettify">,</span><span style=3D"color: #000;" class=3D"styl=
ed-by-prettify"> flag_type f</span><span style=3D"color: #660;" class=3D"st=
yled-by-prettify">)</span><span style=3D"color: #000;" class=3D"styled-by-p=
rettify"> </span><span style=3D"color: #660;" class=3D"styled-by-prettify">=
=3D</span><span style=3D"color: #000;" class=3D"styled-by-prettify"> </span=
><span style=3D"color: #008;" class=3D"styled-by-prettify">delete</span><sp=
an style=3D"color: #660;" class=3D"styled-by-prettify">;</span></div></code=
></div><div><font face=3D"arial, sans-serif"><br>So cases with nullptr woul=
d be caught at compile time.</font></div><div><font face=3D"arial, sans-ser=
if"><br></font></div><div><font face=3D"arial, sans-serif">I have checked t=
his with clang++3.7.</font></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/33981a62-eba4-4a31-a9ae-4d89ca671667%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/33981a62-eba4-4a31-a9ae-4d89ca671667=
%40isocpp.org</a>.<br />
------=_Part_12451_372209307.1456322187986--
------=_Part_12450_1584926091.1456322187985--
.
Author: Moritz Klammler <moritz.klammler@gmail.com>
Date: Wed, 24 Feb 2016 16:07:11 +0100
Raw View
Dawid Kurek <dawikur@gmail.com> writes:
> My idea is to add explicitly deleted overloaded ctors:
>
> explicit basic_regex(std::nullptr_t, flag_type f = regex_constants::ECMAScript) = delete;
> basic_regex(const charT* p, size_t len, flag_type f) = delete;
>
> So cases with nullptr would be caught at compile time.
Note that this only prevents passing `nullptr` literally (or via some,
probably `auto`-deduced, variable of type `std::nullptr_t`). This seems
like a contrived problem to me. The far more likely case of
accidentially passing a null pointer returned from some function
my_regexes.emplace_back(std::getenv("MY_OPTIONAL_REGEX"));
would still compile and eventually invoke undefined behavior at
run-time.
Honestly, I wasn't very convinced by this item in Scott Meyer's book.
It seems neither like a problem with the perfect forwarding of
`emplace_back` nor with the constructor of `std::regex`.
If people think that this is a common problem, the standard could
mandate well-defined behavior for `std::regex`'s constructor when
passed a null pointer (eg throwing an exception). But I don't see
anything special about `std::regex` here. Just about nowhere a standard
library function expects a (mandatory) pointer argument, can you get
away with passing a null pointer. Should we overload and delete for
`std::nullp0tr_t` everywhere?
--
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp.org/d/msgid/std-proposals/87k2lum9k0.fsf%40gmail.com.
.
Author: Dawid Kurek <dawikur@gmail.com>
Date: Wed, 24 Feb 2016 10:18:02 -0800 (PST)
Raw View
------=_Part_6145_1476406364.1456337882722
Content-Type: multipart/alternative;
boundary="----=_Part_6146_525328047.1456337882722"
------=_Part_6146_525328047.1456337882722
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
Yeas, agree that this does not solve the entire problem. But this specific=
=20
case is
really easy to handle and doesn't have any runtime overhead (as checking=20
pointer).
If we can prevent this kind of error with compilation error - why not? And=
=20
yes, I think
everywhere where this issue may occur we can overload&delete. Just to have=
=20
this one
extra check available before even running program.
W dniu =C5=9Broda, 24 lutego 2016 16:07:16 UTC+1 u=C5=BCytkownik Moritz Kla=
mmler=20
napisa=C5=82:
>
> Dawid Kurek <daw...@gmail.com <javascript:>> writes:=20
>
> > My idea is to add explicitly deleted overloaded ctors:=20
> >=20
> > explicit basic_regex(std::nullptr_t, flag_type f =3D=20
> regex_constants::ECMAScript) =3D delete;=20
> > basic_regex(const charT* p, size_t len, flag_type f) =3D delete;=20
> >=20
> > So cases with nullptr would be caught at compile time.=20
>
> Note that this only prevents passing `nullptr` literally (or via some,=20
> probably `auto`-deduced, variable of type `std::nullptr_t`). This seems=
=20
> like a contrived problem to me. The far more likely case of=20
> accidentially passing a null pointer returned from some function=20
>
> my_regexes.emplace_back(std::getenv("MY_OPTIONAL_REGEX"));=20
>
> would still compile and eventually invoke undefined behavior at=20
> run-time.=20
>
> Honestly, I wasn't very convinced by this item in Scott Meyer's book.=20
> It seems neither like a problem with the perfect forwarding of=20
> `emplace_back` nor with the constructor of `std::regex`.=20
>
> If people think that this is a common problem, the standard could=20
> mandate well-defined behavior for `std::regex`'s constructor when=20
> passed a null pointer (eg throwing an exception). But I don't see=20
> anything special about `std::regex` here. Just about nowhere a standard=
=20
> library function expects a (mandatory) pointer argument, can you get=20
> away with passing a null pointer. Should we overload and delete for=20
> `std::nullp0tr_t` everywhere?=20
>
--=20
You received this message because you are subscribed to the Google Groups "=
ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.
To post to this group, send email to std-proposals@isocpp.org.
To view this discussion on the web visit https://groups.google.com/a/isocpp=
..org/d/msgid/std-proposals/452861af-f164-46cb-ad19-e1b58450caf2%40isocpp.or=
g.
------=_Part_6146_525328047.1456337882722
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable
<div dir=3D"ltr">Yeas, agree that this does not solve the entire problem. B=
ut this specific case is<div>really easy to handle and doesn't have any=
runtime overhead (as checking pointer).</div><div><br></div><div>If we can=
prevent this kind of error with compilation error - why not? And yes, I th=
ink</div><div>everywhere where this issue may occur we can overload&del=
ete. Just to have this one</div><div>extra check available before even runn=
ing program.<br><br>W dniu =C5=9Broda, 24 lutego 2016 16:07:16 UTC+1 u=C5=
=BCytkownik Moritz Klammler napisa=C5=82:<blockquote class=3D"gmail_quote" =
style=3D"margin: 0;margin-left: 0.8ex;border-left: 1px #ccc solid;padding-l=
eft: 1ex;">Dawid Kurek <<a href=3D"javascript:" target=3D"_blank" gdf-ob=
fuscated-mailto=3D"0RidallOAgAJ" rel=3D"nofollow" onmousedown=3D"this.href=
=3D'javascript:';return true;" onclick=3D"this.href=3D'javascri=
pt:';return true;">daw...@gmail.com</a>> writes:
<br>
<br>> My idea is to add explicitly deleted overloaded ctors:
<br>>
<br>> explicit basic_regex(std::nullptr_t, flag_type f =3D regex_constan=
ts::ECMAScript) =3D delete;
<br>> basic_regex(const charT* p, size_t len, flag_type f) =3D delete;
<br>>
<br>> So cases with nullptr would be caught at compile time.
<br>
<br>Note that this only prevents passing `nullptr` literally (or via some,
<br>probably `auto`-deduced, variable of type `std::nullptr_t`). =C2=A0This=
seems
<br>like a contrived problem to me. =C2=A0The far more likely case of
<br>accidentially passing a null pointer returned from some function
<br>
<br>=C2=A0 =C2=A0 my_regexes.emplace_back(std::<wbr>getenv("MY_OPTIONA=
L_REGEX"));
<br>
<br>would still compile and eventually invoke undefined behavior at
<br>run-time.
<br>
<br>Honestly, I wasn't very convinced by this item in Scott Meyer's=
book.
<br>It seems neither like a problem with the perfect forwarding of
<br>`emplace_back` nor with the constructor of `std::regex`.
<br>
<br>If people think that this is a common problem, the standard could
<br>mandate well-defined behavior for `std::regex`'s constructor when
<br>passed a null pointer (eg throwing an exception). =C2=A0But I don't=
see
<br>anything special about `std::regex` here. =C2=A0Just about nowhere a st=
andard
<br>library function expects a (mandatory) pointer argument, can you get
<br>away with passing a null pointer. =C2=A0Should we overload and delete f=
or
<br>`std::nullp0tr_t` everywhere?
<br></blockquote></div></div>
<p></p>
-- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals" group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to <a href=3D"mailto:std-proposals+unsubscribe@isocpp.org">std-proposa=
ls+unsubscribe@isocpp.org</a>.<br />
To post to this group, send email to <a href=3D"mailto:std-proposals@isocpp=
..org">std-proposals@isocpp.org</a>.<br />
To view this discussion on the web visit <a href=3D"https://groups.google.c=
om/a/isocpp.org/d/msgid/std-proposals/452861af-f164-46cb-ad19-e1b58450caf2%=
40isocpp.org?utm_medium=3Demail&utm_source=3Dfooter">https://groups.google.=
com/a/isocpp.org/d/msgid/std-proposals/452861af-f164-46cb-ad19-e1b58450caf2=
%40isocpp.org</a>.<br />
------=_Part_6146_525328047.1456337882722--
------=_Part_6145_1476406364.1456337882722--
.