220 8700 <1e1da13e-663f-4f98-8f54-595b8f75591e@isocpp.org> article
Path: news.gmane.org!not-for-mail
From: Alexander Bolz <abolz.lists@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: string_view::is_null()
Date: Sun, 19 Jan 2014 12:37:59 -0800 (PST)
Lines: 307
Approved: news@gmane.org
Message-ID: <1e1da13e-663f-4f98-8f54-595b8f75591e@isocpp.org>
References: <CAPOJ94O19N207rjm73tKJSc7K55kOzYxHbY9wtXquk=_uqqMsA@mail.gmail.com> <8E74B747-7450-41E0-8D1E-48C2D6F81535@gmail.com> <CAGNvRgDH=X2h4K_u3zOu7gUNuQbAcNHGNh=HfCRO9qG1mmiG1w@mail.gmail.com> <CANh-dXnytwWwS7E_BGA-xK8E-zw788TJKzM=HJdC-9JbF7+gTQ@mail.gmail.com> <104254A6-C69A-4571-8455-89D7E466D493@gmail.com> <CANh-dXngzdnwZZnLRxd=AXQcqLaQky9Cpdw6pkbH8tFqRyZavw@mail.gmail.com> <6a95bf9c-55c9-4ae2-966f-d1b1f4df6a37@isocpp.org> <52D9E336.1060801@knejp.de> <1B534FD7-B385-4A7E-A718-3C73F0AB61DC@gmail.com> <11f13f8f-1270-427c-8942-94027a181ff4@isocpp.org> <20140119174431.GA16875@faust.lysator.liu.se>
 <52DC20DB.9030303@gmail.com>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: multipart/alternative; 
	boundary="----=_Part_346_17237154.1390163879753"
X-Trace: ger.gmane.org 1390163875 10707 80.91.229.3 (19 Jan 2014 20:37:55 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 19 Jan 2014 20:37:55 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBCAJPLFFWYPBBKHP6CLAKGQE77QZJLA@isocpp.org Sun Jan 19 21:38:02 2014
Return-path: <std-proposals+bncBCAJPLFFWYPBBKHP6CLAKGQE77QZJLA@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pa0-f72.google.com ([209.85.220.72])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBCAJPLFFWYPBBKHP6CLAKGQE77QZJLA@isocpp.org>)
	id 1W4z85-00016h-Ur
	for gclcip-std-proposals@m.gmane.org; Sun, 19 Jan 2014 21:38:02 +0100
Original-Received: by mail-pa0-f72.google.com with SMTP id rd3sf15807509pab.3
        for <gclcip-std-proposals@m.gmane.org>; Sun, 19 Jan 2014 12:38:00 -0800 (PST)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=20120113;
        h=date:from:to:message-id:in-reply-to:references:subject:mime-version
         :x-original-sender:reply-to:precedence:mailing-list:list-id
         :list-post:list-help:list-archive:list-subscribe:list-unsubscribe
         :content-type;
        bh=QwNc/oBepYvLcWf8+SoJ0fQV6ab+p4/ohH8xAvuTi+Y=;
        b=fbBIyyH7WY4Xo4XJlPSW8W7Pm+6f0hB5wyGN/JT4yWihyI8Y6Yik/QbRoDC3mcGW7/
         SCpT8O+u0/4jxbWghBl/XUMvI7rLWeYmnDAHbIqyJYBOHSMpjjf2V/LBkr7KI5shAePX
         2mQWuNxfST2Z3Hw1EmAFlG46HK0PHt4ZetxPlF9665qs0A+lD67rm5ySlDDJqadc6eJM
         4zEJW6pAtGssjea1J+NKbnw8UHKixlmqOP6UXD+ofQ9Xcp+KlrCgdz+7q2JpqaMVmEjJ
         CRObC+3fRi+OQP8GNVP2s4ONuklwxCBBN3GGrKTWKNLoIUJVr4EJj63scYc9sxRMPdm/
         xrpQ==
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:date:from:to:message-id:in-reply-to:references
         :subject:mime-version:x-original-sender:reply-to:precedence
         :mailing-list:list-id:list-post:list-help:list-archive
         :list-subscribe:list-unsubscribe:content-type;
        bh=QwNc/oBepYvLcWf8+SoJ0fQV6ab+p4/ohH8xAvuTi+Y=;
        b=Kv98kVTeA9slklpT4YySnE4fIRixENNpM/0K99p58zLSQOg/qCb9yHgutbTPYrwQNj
         I9NC0qkA9bStAQRhbdD0kXLTriZBwRae8SAKoqfn5VvjjN5P2KXBuFatHhq1B0TvKwnE
         NDtnjrBq85HDenwoFw3J1/CBMgsjOD7CsogTNbno4p9AtBf36foW724YZGiwwgh8Sq2g
         LotiADeUBJ8NEYVLuHcovpIJKtHrPQRnaofYHESTweDvVqS5m9v9fS5xH8nA5TVXuad+
         EXnO7b+gdYmcIFJoKfyR1T4c02oI/C/0kYdQDTxFtVIVxOCkod3jZ/3BVJ7puBAUJGVc
         iyUA==
X-Gm-Message-State: ALoCoQmtFntGmr9Mg98cvIJYsdO3nMGvJU+aYUO2Nw13EwEAvFE+5YyNN2wjKPn89l5oZH/WEnaV
X-Received: by 10.66.26.132 with SMTP id l4mr5092302pag.2.1390163880807;
        Sun, 19 Jan 2014 12:38:00 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.128.200 with SMTP id nq8ls1609332qeb.95.gmail; Sun, 19 Jan
 2014 12:38:00 -0800 (PST)
X-Received: by 10.140.91.72 with SMTP id y66mr2590qgd.23.1390163880158;
        Sun, 19 Jan 2014 12:38:00 -0800 (PST)
In-Reply-To: <52DC20DB.9030303@gmail.com>
X-Original-Sender: abolz.lists@gmail.com
Precedence: list
Mailing-list: list std-proposals@isocpp.org; contact std-proposals+owners@isocpp.org
List-ID: <std-proposals.isocpp.org>
X-Google-Group-Id: 399137483710
List-Post: <http://groups.google.com/a/isocpp.org/group/std-proposals/post>, <mailto:std-proposals@isocpp.org>
List-Help: <http://support.google.com/a/isocpp.org/bin/topic.py?topic=25838>, <mailto:std-proposals+help@isocpp.org>
List-Archive: <http://groups.google.com/a/isocpp.org/group/std-proposals/>
List-Subscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:std-proposals+subscribe@isocpp.org>
List-Unsubscribe: <http://groups.google.com/a/isocpp.org/group/std-proposals/subscribe>,
 <mailto:googlegroups-manage+399137483710+unsubscribe@googlegroups.com>
Xref: news.gmane.org gmane.comp.lang.c++.isocpp.proposals:8700
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/8700>

------=_Part_346_17237154.1390163879753
Content-Type: text/plain; charset=UTF-8

Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb Paul Tessier:

> On 01/19/2014 12:44 PM, Magnus Fromreide wrote: 
> > On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote: 
> >> On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote: 
> >>> On Jan 17, 2014, at 6:13 PM, Miro Knejp <mi...@knejp.de<javascript:>> 
> >>> wrote: 
> >>> 
> >>>>> - both of these methods are impossible if the presumptions stated 
> above 
> >>> "begin() should never return nullptr" and "we don't need a special 
> >>> is_null()". Well, not entirely. Of course you could create some bogus 
> >>> object and use its address instead of nullptr. 
> >>>> Why not set the string_view to "" in the default constructor? 
> >>> I believe that this is the current proposal. 
> >>> 
> >>> However, this requires creating a global variable (which some 
> >>> implementations will put in the code segment) for each default 
> constructed 
> >>> string_view (yes, some implementations will merge them together in the 
> same 
> >>> translation unit). 
> >>> 
> >> I thought somebody had proposed a "will-probably-work" solution 
> involving 
> >> casts of non-zero values to a pointer to avoid the global variable, but 
> >> here's another solution I believe is safe and well-defined: 
> >> 
> >> Nothing in the current spec requires that the data() function return 
> the 
> >> same value for distinct default-constructed string_view instances.  So 
> use 
> >> the following data members: 
> >> 
> >>    const charT * m_ptr; 
> >>    union { 
> >>       size_t m_len; 
> >>       charT m_nul; 
> >>    }; 
> >> 
> >> and have the default constructor set m_ptr to &m_nul and m_len to 0. 
>  The 
> >> result is a (unique) empty string reference. 
> >> 
> >> I've tested this by modifying Boost's implementation and it works fine. 
> >> Note that only the m_len data member is actually used and is always 
> zero 
> >> for the default-constructed value.  There's no issue about accessing 
> the 
> >> other union member because when size() is zero you can't legitimately 
> >> dereference data() unless you know from construction that it's pointing 
> >> into a non-empty range (and in this case it doesn't). 
> > I have thought in a similar direction, but the problem is if you have 
> two 
> > string_view's, s1 and s2. Assume that s1 i empty, does the statement 
> > s2 = s1; imply that s2.data() == s1.data()? 
> > 
> > Then what happens if s1 is deallocated and it's memory is returned to 
> the 
> > system, won't s2.m_ptr then hold an illegal pointer value, one of those 
> > where even loading it could trigger a hardware trap on some 
> architectures. 
> > 
> > /MF 
> > 
>
> If s1 and s2 are empty, only access to the metadata is rational. Using 
> operator[], front(), back(), etc. will produce undefined behavior. 
> s1.data() and s2.data() are irrelevant because, it points to the 
> beginning of a range of zero length.  One could just as easily set 
> data() to null or some random value, when the string_view becomes empty 
> but, such actions are unneeded.  The equality comparison is based on the 
> equality of the two ordered sets of characters from s1 and s2.  All 
> empty views are equally empty and does not imply ( s2.data() == 
> s1.data() ), just as ( s1 == s2 ) does not imply that ( &s1 == &s2 ). 
>
> If &s1 is deallocated and falls into a protected segment, any access to 
> it will trap, just like any other object.  If both s1 and s2 where 
> referencing a string that was deallocated before they both became empty 
> then, both would trap, unless data() is randomized or set to some safe 
> location as I mentioned above but, this would be pointless as accessing 
> the referenced string of an empty view is undefined behavior. 
>
>
> To me the prevention of null being returned by data() is just an 
> artifact inherited from std::string.  It seem like an early and 
> incomplete error check.  You could also argue that all unreachable 
> segments be restricted. 
>
> If string_view was only a range of a std:string, forwarding all 
> std::string's warts through the interface would not be completely 
> unexpected.  Especially when the wrapper is such a lightweight class. 
> Yet, string_view serves a wider purpose therefore, those warts should 
> ignored. I argue that std::string's interface should be relaxed and, not 
> that string_view's be restricted. 
>
> Consider std::array< char, 0 >.  It's data() will return null, and the 
> rest of it's members behave as rationally.  


This is not correct. I just looked it up in N3797:
23.3.2.8. says "begin() == end() == unique value. The return value of data()is unspecified"
 

> I see no reason for 
> string_view not to behave in a similar fashion.  While std:string may 
> never return null for it's data(), it is inconsequential as string_view 
> maybe constructed from other sources. 
>
> Having a is_null() seems excessive. data() should be allowed to be null, 
> as this seems the simplest solution.  Following the behavior of 
> std::array< char, 0 > seems to solve many of the other problems in the 
> interface being unable to handle data() and begin() being null. 
>
> While string_view is modeled after std::string's interface, the newer 
> std::array interface seems more flexible and also solves the default 
> empty initialization problem.  Besides, any object that behaves 
> rationally when zeroed out, say by memset, is a plus. 
>
>
>

-- 

--- 
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.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

------=_Part_346_17237154.1390163879753
Content-Type: text/html; charset=UTF-8
Content-Transfer-Encoding: quoted-printable

<div dir=3D"ltr">Am Sonntag, 19. Januar 2014 20:00:43 UTC+1 schrieb Paul Te=
ssier:<br><blockquote class=3D"gmail_quote" style=3D"margin: 0;margin-left:=
 0.8ex;border-left: 1px #ccc solid;padding-left: 1ex;">On 01/19/2014 12:44 =
PM, Magnus Fromreide wrote:
<br>&gt; On Sun, Jan 19, 2014 at 07:55:32AM -0800, Peter Bigot wrote:
<br>&gt;&gt; On Friday, January 17, 2014 10:19:07 PM UTC-6, Marshall wrote:
<br>&gt;&gt;&gt; On Jan 17, 2014, at 6:13 PM, Miro Knejp &lt;<a>mi...@knejp=
..de</a> &lt;javascript:&gt;&gt;
<br>&gt;&gt;&gt; wrote:
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt;&gt;&gt; - both of these methods are impossible if the pres=
umptions stated above
<br>&gt;&gt;&gt; "begin() should never return nullptr" and "we don't need a=
 special
<br>&gt;&gt;&gt; is_null()". Well, not entirely. Of course you could create=
 some bogus
<br>&gt;&gt;&gt; object and use its address instead of nullptr.
<br>&gt;&gt;&gt;&gt; Why not set the string_view to "" in the default const=
ructor?
<br>&gt;&gt;&gt; I believe that this is the current proposal.
<br>&gt;&gt;&gt;
<br>&gt;&gt;&gt; However, this requires creating a global variable (which s=
ome
<br>&gt;&gt;&gt; implementations will put in the code segment) for each def=
ault constructed
<br>&gt;&gt;&gt; string_view (yes, some implementations will merge them tog=
ether in the same
<br>&gt;&gt;&gt; translation unit).
<br>&gt;&gt;&gt;
<br>&gt;&gt; I thought somebody had proposed a "will-probably-work" solutio=
n involving
<br>&gt;&gt; casts of non-zero values to a pointer to avoid the global vari=
able, but
<br>&gt;&gt; here's another solution I believe is safe and well-defined:
<br>&gt;&gt;
<br>&gt;&gt; Nothing in the current spec requires that the data() function =
return the
<br>&gt;&gt; same value for distinct default-constructed string_view instan=
ces. &nbsp;So use
<br>&gt;&gt; the following data members:
<br>&gt;&gt;
<br>&gt;&gt; &nbsp; &nbsp;const charT * m_ptr;
<br>&gt;&gt; &nbsp; &nbsp;union {
<br>&gt;&gt; &nbsp; &nbsp; &nbsp; size_t m_len;
<br>&gt;&gt; &nbsp; &nbsp; &nbsp; charT m_nul;
<br>&gt;&gt; &nbsp; &nbsp;};
<br>&gt;&gt;
<br>&gt;&gt; and have the default constructor set m_ptr to &amp;m_nul and m=
_len to 0. &nbsp;The
<br>&gt;&gt; result is a (unique) empty string reference.
<br>&gt;&gt;
<br>&gt;&gt; I've tested this by modifying Boost's implementation and it wo=
rks fine.
<br>&gt;&gt; Note that only the m_len data member is actually used and is a=
lways zero
<br>&gt;&gt; for the default-constructed value. &nbsp;There's no issue abou=
t accessing the
<br>&gt;&gt; other union member because when size() is zero you can't legit=
imately
<br>&gt;&gt; dereference data() unless you know from construction that it's=
 pointing
<br>&gt;&gt; into a non-empty range (and in this case it doesn't).
<br>&gt; I have thought in a similar direction, but the problem is if you h=
ave two
<br>&gt; string_view's, s1 and s2. Assume that s1 i empty, does the stateme=
nt
<br>&gt; s2 =3D s1; imply that s2.data() =3D=3D s1.data()?
<br>&gt;
<br>&gt; Then what happens if s1 is deallocated and it's memory is returned=
 to the
<br>&gt; system, won't s2.m_ptr then hold an illegal pointer value, one of =
those
<br>&gt; where even loading it could trigger a hardware trap on some archit=
ectures.
<br>&gt;
<br>&gt; /MF
<br>&gt;
<br>
<br>If s1 and s2 are empty, only access to the metadata is rational. Using=
=20
<br>operator[], front(), back(), etc. will produce undefined behavior.
<br>s1.data() and s2.data() are irrelevant because, it points to the=20
<br>beginning of a range of zero length. &nbsp;One could just as easily set=
=20
<br>data() to null or some random value, when the string_view becomes empty=
=20
<br>but, such actions are unneeded. &nbsp;The equality comparison is based =
on the=20
<br>equality of the two ordered sets of characters from s1 and s2. &nbsp;Al=
l=20
<br>empty views are equally empty and does not imply ( s2.data() =3D=3D=20
<br>s1.data() ), just as ( s1 =3D=3D s2 ) does not imply that ( &amp;s1 =3D=
=3D &amp;s2 ).
<br>
<br>If &amp;s1 is deallocated and falls into a protected segment, any acces=
s to=20
<br>it will trap, just like any other object. &nbsp;If both s1 and s2 where=
=20
<br>referencing a string that was deallocated before they both became empty=
=20
<br>then, both would trap, unless data() is randomized or set to some safe=
=20
<br>location as I mentioned above but, this would be pointless as accessing=
=20
<br>the referenced string of an empty view is undefined behavior.
<br>
<br>
<br>To me the prevention of null being returned by data() is just an=20
<br>artifact inherited from std::string. &nbsp;It seem like an early and=20
<br>incomplete error check. &nbsp;You could also argue that all unreachable=
=20
<br>segments be restricted.
<br>
<br>If string_view was only a range of a std:string, forwarding all=20
<br>std::string's warts through the interface would not be completely=20
<br>unexpected. &nbsp;Especially when the wrapper is such a lightweight cla=
ss.=20
<br>Yet, string_view serves a wider purpose therefore, those warts should=
=20
<br>ignored. I argue that std::string's interface should be relaxed and, no=
t=20
<br>that string_view's be restricted.
<br>
<br>Consider std::array&lt; char, 0 &gt;. &nbsp;It's data() will return nul=
l, and the=20
<br>rest of it's members behave as rationally. &nbsp;</blockquote><div><br>=
</div><div>This is not correct. I just looked it up in N3797:</div><div>23.=
3.2.8. says "<font face=3D"courier new, monospace">begin() =3D=3D end() =3D=
=3D</font> unique value. The return value of <font face=3D"courier new, mon=
ospace">data()</font> is unspecified"<br></div><div>&nbsp;</div><blockquote=
 class=3D"gmail_quote" style=3D"margin: 0;margin-left: 0.8ex;border-left: 1=
px #ccc solid;padding-left: 1ex;">I see no reason for=20
<br>string_view not to behave in a similar fashion. &nbsp;While std:string =
may=20
<br>never return null for it's data(), it is inconsequential as string_view=
=20
<br>maybe constructed from other sources.
<br>
<br>Having a is_null() seems excessive. data() should be allowed to be null=
,=20
<br>as this seems the simplest solution. &nbsp;Following the behavior of=20
<br>std::array&lt; char, 0 &gt; seems to solve many of the other problems i=
n the=20
<br>interface being unable to handle data() and begin() being null.
<br>
<br>While string_view is modeled after std::string's interface, the newer=
=20
<br>std::array interface seems more flexible and also solves the default=20
<br>empty initialization problem. &nbsp;Besides, any object that behaves=20
<br>rationally when zeroed out, say by memset, is a plus.
<br>
<br>
<br></blockquote></div>

<p></p>

-- <br />
&nbsp;<br />
--- <br />
You received this message because you are subscribed to the Google Groups &=
quot;ISO C++ Standard - Future Proposals&quot; group.<br />
To unsubscribe from this group and stop receiving emails from it, send an e=
mail to std-proposals+unsubscribe@isocpp.org.<br />
To post to this group, send email to std-proposals@isocpp.org.<br />
Visit this group at <a href=3D"http://groups.google.com/a/isocpp.org/group/=
std-proposals/">http://groups.google.com/a/isocpp.org/group/std-proposals/<=
/a>.<br />

------=_Part_346_17237154.1390163879753--

.
