<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Oct 11, 2017 at 9:18 PM, David Jones <span dir="ltr"><<a href="mailto:dlj@google.com" target="_blank">dlj@google.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span class="gmail-">On Wed, Oct 11, 2017 at 6:11 PM, Eric Fiselier <span dir="ltr"><<a href="mailto:eric@efcs.ca" class="gmail-m_-7741034651074637397m_-2874225490426550490cremed gmail-m_-7741034651074637397cremed" target="_blank">eric@efcs.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote"><span>On Wed, Oct 11, 2017 at 6:30 PM, David Jones via cfe-dev <span dir="ltr"><<a href="mailto:cfe-dev@lists.llvm.org" class="gmail-m_-7741034651074637397m_-2874225490426550490cremed gmail-m_-7741034651074637397cremed" target="_blank">cfe-dev@lists.llvm.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Hello,<div><br></div><div>I'm currently working on migrating a large (100M+ LOC) C++ codebase to libc++. One particular pain point are the absence of constexpr constructors for std::pair, std::array, and std::tuple under C++11. </div></div></blockquote><div><br></div></span><div>Nit: std::array shouldn't have any constructors. But the other members are conditionally constexpr.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div>Some older versions of libstdc++ expose constexpr constructors under C++11, while libc++ does not; this causes build failures when using libc++.</div></div></blockquote><div><br></div></span><div>Hmm, just to clarify, it's not just older versions of libstdc++ that do this, but newer ones as well. It's not like they removed it later.</div><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>I would like to add a configuration variable that enables the constexpr qualifier on these constructors for C++11 or later, with the intent of advancing the C++ version as quickly as possible. Most of the uses can be trivially replaced by removing constexpr or switching to arrays, but this is churn for code which will (hopefully) soon be compliant anyhow.</div></div></blockquote><div><br></div></span><div>I'm actually quite sympathetic to enabling this extension by default, since MSVC and libstdc++ both seem to. We're the odd man out.</div><div>If everybody else can safely get away with this, we should be able to as well.</div><div><br></div><div>BTW, by "C++11 or later" you mean "C++11" because they're already required to be constexpr in C++14.</div><span><div></div></span></div></div></div></blockquote><div><br></div></span><div>Naturally, yes... although what I really wanted to get at was "not C++03 or earlier."</div><span class="gmail-"><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><span><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><br></div><div>I suspect this may be useful for other codebases that build in C++11 mode to move to libc++... however, this would be a non-conforming extension. Adding a configuration option in __<a href="http://config_site.in" class="gmail-m_-7741034651074637397m_-2874225490426550490cremed gmail-m_-7741034651074637397cremed" target="_blank">config_site.in</a> (with the default being conforming behaviour) seems like it may be the most reasonable way to add the option.</div></div></blockquote><div><br></div></span><div>The extension is technically slightly worse than non-conforming; it's explicitly forbidden. Implementations are not allowed to apply constexpr where it isn't specified. However I think this rule should be relaxed to allow implementations to backport newly added constexpr specifiers to older dialects as an extension, as is this case.</div><div><br></div><div>However my main concern with this as an on-by-default extension is that it has the potential to break code. There are certain constexpr evaluations that might result in a hard compile error that wouldn't before. I think Clang has fixed most of these cases though.</div><div><br></div></div></div></div></blockquote><div><br></div></span><div>Right... I think on-by-default might be a bit too much.</div></div></div></div></blockquote><div><br></div><div>Thankfully, despite my short-lived best efforts so far, I haven't been able to construct a test case that I care about which breaks.</div><div>Admittedly, older Clang versions have problematic examples, but I suspect very few people mix very old Clang versions</div><div>with brand new STL headers.</div><div><br></div><div>For example, the following code has silently different behavior across dialects:<br><br></div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254);font-family:"Fira Mono";font-size:14px;line-height:19px;white-space:pre"><span style="color:rgb(0,0,255)">static</span> std::pair<<span style="color:rgb(0,0,255)">int</span>, <span style="color:rgb(0,0,255)">int</span>> p(<span style="color:rgb(9,136,90)">1</span>, <span style="color:rgb(9,136,90)">2</span>);</div></div><div><br></div><div>In C++14, the initialization of `p` occurs at compile time, but in C++11, because the constructor is not constexpr,</div><div>the initialization happens at run time. This bug also effects types composed using pair, Ex:<br><br></div><div><div style="line-height:19px"><div style="color:rgb(0,0,0);font-family:"Fira Mono";font-size:14px;white-space:pre;background-color:rgb(255,255,254)"><span style="color:rgb(0,0,255)">struct</span> MyType { </div><div style="color:rgb(0,0,0);font-family:"Fira Mono";font-size:14px;white-space:pre;background-color:rgb(255,255,254)">  <span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">class</span> ...Args></div><div style="color:rgb(0,0,0);font-family:"Fira Mono";font-size:14px;white-space:pre;background-color:rgb(255,255,254)">  <span style="color:rgb(0,0,255)">constexpr</span> MyType(Args... args) : p(args...) {}</div><div style="color:rgb(0,0,0);font-family:"Fira Mono";font-size:14px;white-space:pre;background-color:rgb(255,255,254)">  std::pair<<span style="color:rgb(0,0,255)">int</span>, <span style="color:rgb(0,0,255)">int</span>> x;</div><div style="color:rgb(0,0,0);font-family:"Fira Mono";font-size:14px;white-space:pre;background-color:rgb(255,255,254)">};</div><br>Such a type implicitly depends on `pair`s constructors to be constexpr in order for</div></div><div style="line-height:19px">for instances of the class with static storage duration to be safely constructed during</div><div style="line-height:19px">constant initialization.</div><div style="line-height:19px"><br></div><div style="line-height:19px">IMHO, It's more important for libc++ to provide consistent and safe semantics for `pair`</div><div style="line-height:19px">and `tuple` across dialects than it is to be pedantically correct. One thing Howard Hinnent</div><div style="line-height:19px">taught me was to act in the best interest of your users; a pedantically correct implementation</div><div style="line-height:19px">without users is of value to no one.</div><div style="line-height:19px"><br></div><div style="line-height:19px">Therefore, I would rather adopt the extension universally, as everybody else does, unless I</div><div style="line-height:19px">can come up with sensible examples of use-cases that break after introducing the extension,</div><div style="line-height:19px"><br></div><div style="line-height:19px">@Marshall, would you be supportive of this?</div></div><br></div></div>