<div style="font-family: arial, helvetica, sans-serif"><font size="2"><div class="gmail_quote">On Mon, Jun 18, 2012 at 9:48 AM, Marshall Clow <span dir="ltr"><<a href="mailto:mclow.lists@gmail.com" target="_blank">mclow.lists@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div class="im">On Jun 18, 2012, at 8:47 AM, David Blaikie wrote:<br>
> On Mon, Jun 18, 2012 at 8:36 AM, Marshall Clow <<a href="mailto:mclow.lists@gmail.com">mclow.lists@gmail.com</a>> wrote:<br>
>> Modeled on the one in ArrayRef<br>
>><br>
>>    /// Construct an string ref from a C array.<br>
>>    template <size_t N><br>
>>    /*implicit*/ StringRef(const char (&Arr)[N])<br>
>>      : Data(Arr), Length(N) {}<br>
>><br>
><br>
</div><div class="im">> One possible problem with this is that if you construct a StringRef<br>
> from a string literal, you'll end up including the '\0' inside it.<br>
<br>
</div>Ok - I can see that.<br>
<div class="im">><br>
> (also, when I tried this myself a few months ago, there's at least one<br>
> case where a StringRef is constructed from a large fixed-size buffer<br>
> on the stack - when using this ctor, it obviously gets the size quite<br>
> wrong)<br>
<br>
</div>Interesting. Do you remember where that was?<br>
<div class="im"><br>
> That being said, I like the idea, I'm just not sure the right way to<br>
> implement it - when I was experimenting with this I implemented it<br>
> with a '\0' check for the last character (truncating the size by one<br>
> when present, and leaving it at the full size when it wasn't present)<br>
<br>
</div>Ok.<br>
<div class="im"><br>
> - and added an assert for strlen(Data) == Length to catch the buffer<br>
> case (which means the ctor didn't provide performance improvements in<br>
> debug builds but only in release builds).<br>
<br>
</div>I see three problems here:<br>
1) Constructing from string literal gives one too large. This is easily fixed.<br>
2) Your case above.<br>
3) The general case, where you have an array that may contain a NULL somewhere in the middle.<br>
<br>
(These last two might turn out to be the same case.)<br>
<br>
The second case, I don't see as a problem, given that the ( data, len ) constructor does not enforce the invariant that StringRef::Length () == strlen ( StringRef.data()).<br>
I know that StringRef.data() doesn't have to be NULL-terminated, but I don't see any care being taken to deal with embedded NULL characters, either.<br>
<br>
Maybe the confusion here is due to the fact that this would create a second one-argument constructor, and it would not be clear which was being chosen:<br>
<br>
        StringRef ( array )     - gives a reference to the entire array<br>
        StringRef ( pointer )  - gives a reference to the (null-terminated) string<br>
<br>
Ok - I'm not sure I see a good way to disambiguate those (or rather, for the user to know which is being called, given that arrays decay to pointers if you look at them funny)<br>
<br>
Dang.  Any ideas?</blockquote><div><br></div><div>Folks, why does this matter?</div><div><br></div><div>So, the concern about 'strlen' performance is, I suspect, a red herring. Clang/LLVM is very good at removing 'strlen' calls to string literals. I would also expect it to  be very good at inlining StringRef("foo"). In fact, if it fails to inline that,  *ever*, it's  a flat out bug, file it  against  me.</div>
<div><br></div><div>Once the inline happens, the performance problem vanishes. So maybe we can just use strlen and call it a day?</div></div></font></div>