<div dir="ltr"><div dir="ltr" class="gmail_msg">StringRef's copy ctor would have to be constexpr, which I believe it is - implicitly/the default.<br class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg">$ cat test.cpp</div><div class="gmail_msg">struct base { };</div><div class="gmail_msg">struct derived : base {</div><div class="gmail_msg">  constexpr derived(int i) { }</div><div class="gmail_msg">};</div><div class="gmail_msg">struct outer { base b; };</div><div class="gmail_msg">constexpr outer o{derived(3)};</div><div class="gmail_msg">$ clang++-tot test.cpp -fsyntax-only -std=c++11</div><div class="gmail_msg">$ </div></div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Tue, Dec 13, 2016 at 11:29 AM Mehdi Amini <<a href="mailto:mehdi.amini@apple.com" class="gmail_msg" target="_blank">mehdi.amini@apple.com</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Dec 13, 2016, at 10:36 AM, David Blaikie <<a href="mailto:dblaikie@gmail.com" class="gmail_msg" target="_blank">dblaikie@gmail.com</a>> wrote:</div><br class="m_-5113956111835480092m_-5951010500870792891Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg">(just repeating what I said on IRC for context)<br class="gmail_msg"><br class="gmail_msg">My thinking was that StringLiteral would be used only for temporary expressions (and that even the type of the global tables would be StringRef, not StringLiteral) - so this type wouldn't end up in any APIs, etc, keeping it fairly simple/isolated/non-intrusive/etc.<br class="gmail_msg"></div></div></blockquote><div class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">If the type of the global is StringRef, doesn’t this make it invoking the copy ctor from StringRef when initializing from StringLiteral? Would this still be constexpr?</div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div dir="ltr" class="gmail_msg"><br class="gmail_msg">If the type is going to make its way into API usage, then I worry about possible misuse (such as constructing it from a non-literal in one callsite to such an API (possibly an array without a null terminator, or with a null terminator not at the end (such as a fixed length buffer populated with a shorter value)), even if the other started off as using it in the current intended way).<br class="gmail_msg"><br class="gmail_msg">I know lld are dabbling with a string type designed to caryr the extra semantic info of a null terminator (StringRefZ), which might fit into all of this somehow. (maybe StringLiteral can be converted to StringRefZ, for example)<br class="gmail_msg"><br class="gmail_msg">Or maybe I'm just off in the weeds and StringLiteral won't ever be so constrained as to be only used in global initializers. I certainly don't have the most context here and will defer to others who do.</div><br class="gmail_msg"><div class="gmail_quote gmail_msg"><div dir="ltr" class="gmail_msg">On Tue, Dec 13, 2016 at 10:30 AM Zachary Turner via Phabricator <<a href="mailto:reviews@reviews.llvm.org" class="gmail_msg" target="_blank">reviews@reviews.llvm.org</a>> wrote:<br class="gmail_msg"></div><blockquote class="gmail_quote gmail_msg" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">zturner created this revision.<br class="gmail_msg">
zturner added reviewers: dblaikie, mehdi_amini, malcolm.parsons, chandlerc.<br class="gmail_msg">
zturner added a subscriber: llvm-commits.<br class="gmail_msg">
<br class="gmail_msg">
string literals are necessarily null-terminated, so it makes sense to provide a `c_str()` method to treat it as a null terminated string.<br class="gmail_msg">
<br class="gmail_msg">
In practice this arises because you might imagine a global table that contains option names which you want to pass to something like `getopt_long_only`, but in other situations you might want to do some comparisons on the option name (for example, is `--foo` in the options table), where you want to make use of `StringRef` comparison operators.  Of course, there are tons of other system calls or library calls which we don't have control over that take `const char*` and where we pull arguments for these functiosn from a global table of `const char *`, so this doesn't seem like just a one-off case.<br class="gmail_msg">
<br class="gmail_msg">
Writing `.str().c_str()` for these cases is problematic since it means we cannot assume the storage will live longer than the current statement, plus it's just inefficient since we're unnecessarily incurring a copy.<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
<a href="https://reviews.llvm.org/D27721" rel="noreferrer" class="gmail_msg" target="_blank">https://reviews.llvm.org/D27721</a><br class="gmail_msg">
<br class="gmail_msg">
Files:<br class="gmail_msg">
  include/llvm/ADT/StringRef.h<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
Index: include/llvm/ADT/StringRef.h<br class="gmail_msg">
===================================================================<br class="gmail_msg">
--- include/llvm/ADT/StringRef.h<br class="gmail_msg">
+++ include/llvm/ADT/StringRef.h<br class="gmail_msg">
@@ -854,6 +854,8 @@<br class="gmail_msg">
   public:<br class="gmail_msg">
     template <size_t N><br class="gmail_msg">
     constexpr StringLiteral(const char (&Str)[N]) : StringRef(Str, N - 1) {}<br class="gmail_msg">
+<br class="gmail_msg">
+    const char *c_str() const { return data(); }<br class="gmail_msg">
   };<br class="gmail_msg">
<br class="gmail_msg">
   /// @name StringRef Comparison Operators<br class="gmail_msg">
<br class="gmail_msg">
<br class="gmail_msg">
</blockquote></div>
</div></blockquote></div></div></blockquote></div></div>