220 8696 <52DC20DB.9030303@gmail.com> article
Path: news.gmane.org!not-for-mail
From: "Paul A. Tessier" <phernost@gmail.com>
Newsgroups: gmane.comp.lang.c++.isocpp.proposals
Subject: Re: string_view::is_null()
Date: Sun, 19 Jan 2014 14:00:43 -0500
Lines: 107
Approved: news@gmane.org
Message-ID: <52DC20DB.9030303@gmail.com>
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>
Reply-To: std-proposals@isocpp.org
NNTP-Posting-Host: plane.gmane.org
Mime-Version: 1.0
Content-Type: text/plain; charset=UTF-8; format=flowed
X-Trace: ger.gmane.org 1390158044 13282 80.91.229.3 (19 Jan 2014 19:00:44 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Sun, 19 Jan 2014 19:00:44 +0000 (UTC)
To: std-proposals@isocpp.org
Original-X-From: std-proposals+bncBDDYTQX56INBBX6B6CLAKGQEAXUY6FQ@isocpp.org Sun Jan 19 20:00:51 2014
Return-path: <std-proposals+bncBDDYTQX56INBBX6B6CLAKGQEAXUY6FQ@isocpp.org>
Envelope-to: gclcip-std-proposals@m.gmane.org
Original-Received: from mail-pb0-f69.google.com ([209.85.160.69])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <std-proposals+bncBDDYTQX56INBBX6B6CLAKGQEAXUY6FQ@isocpp.org>)
	id 1W4xc0-0000CQ-TH
	for gclcip-std-proposals@m.gmane.org; Sun, 19 Jan 2014 20:00:49 +0100
Original-Received: by mail-pb0-f69.google.com with SMTP id md12sf3632655pbc.4
        for <gclcip-std-proposals@m.gmane.org>; Sun, 19 Jan 2014 11:00:47 -0800 (PST)
X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=1e100.net; s=20130820;
        h=x-gm-message-state:message-id:date:from:user-agent:mime-version:to
         :subject:references:in-reply-to:x-original-sender
         :x-original-authentication-results:reply-to:precedence:mailing-list
         :list-id:list-post:list-help:list-archive:list-subscribe
         :list-unsubscribe:content-type;
        bh=vrYsO1ngzWTcYkwJMKP0N/SmYMVrHVQv4FzUUQrrPKE=;
        b=V1wRMBTbsx2Bs8ZY+A/v0xP5QykNVPydMsU8N9dVAoIMP8cDJRTqBTyg/Hf88p78gY
         Bt9huNjBMF3xRWkKbp8hJdfPIcrAHW5jy8r+bA0rfO9YkWLZWomhcXe1KO+7w9FTwP4r
         qXQYKZjlMcNRXUAdP7licc39ijycJYdQHyZF4F852lgHmLVKHC7j02D1X6qTYdKCjFvz
         FUb2nUSggKyqZU6Q605MIzFAeQlNtTSJXBzvzDFkIsvnc9pXf3ceZkCQIs9EEXe02T0g
         XpvXOn3pls8B6Yg28J5EeNK7qZIpt4vvVXM3p97i7vfDT121jYZMiiAjRex3uzZZFn4g
         YPfQ==
X-Gm-Message-State: ALoCoQmZjqLMHNV4ka6Sa6W3Fmz5KToRNZmxOtUXXz1jHfbMBKvjyR3e6JvDoFW1r5XVafSxebKY
X-Received: by 10.66.222.105 with SMTP id ql9mr5747394pac.9.1390158047733;
        Sun, 19 Jan 2014 11:00:47 -0800 (PST)
X-BeenThere: std-proposals@isocpp.org
Original-Received: by 10.49.40.164 with SMTP id y4ls1633000qek.89.gmail; Sun, 19 Jan
 2014 11:00:47 -0800 (PST)
X-Received: by 10.229.84.201 with SMTP id k9mr22101877qcl.18.1390158047182;
        Sun, 19 Jan 2014 11:00:47 -0800 (PST)
Original-Received: from mail-qa0-x229.google.com (mail-qa0-x229.google.com [2607:f8b0:400d:c00::229])
        by mx.google.com with ESMTPS id 75si7682274qgv.147.2014.01.19.11.00.46
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 19 Jan 2014 11:00:46 -0800 (PST)
Received-SPF: pass (google.com: domain of phernost@gmail.com designates 2607:f8b0:400d:c00::229 as permitted sender) client-ip=2607:f8b0:400d:c00::229;
Original-Received: by mail-qa0-f41.google.com with SMTP id w8so4961236qac.28
        for <std-proposals@isocpp.org>; Sun, 19 Jan 2014 11:00:46 -0800 (PST)
X-Received: by 10.140.96.17 with SMTP id j17mr21106112qge.112.1390158046054;
        Sun, 19 Jan 2014 11:00:46 -0800 (PST)
Original-Received: from [192.168.0.150] (c-71-192-182-216.hsd1.ma.comcast.net. [71.192.182.216])
        by mx.google.com with ESMTPSA id 80sm2035432qgx.12.2014.01.19.11.00.44
        for <std-proposals@isocpp.org>
        (version=TLSv1 cipher=ECDHE-RSA-RC4-SHA bits=128/128);
        Sun, 19 Jan 2014 11:00:45 -0800 (PST)
User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.2.0
In-Reply-To: <20140119174431.GA16875@faust.lysator.liu.se>
X-Original-Sender: phernost@gmail.com
X-Original-Authentication-Results: mx.google.com;       spf=pass (google.com:
 domain of phernost@gmail.com designates 2607:f8b0:400d:c00::229 as permitted
 sender) smtp.mail=phernost@gmail.com;       dkim=pass header.i=@gmail.com;
       dmarc=pass (p=NONE dis=NONE) header.from=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:8696
Archived-At: <http://permalink.gmane.org/gmane.comp.lang.c++.isocpp.proposals/8696>

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.  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/.

.
