<div dir="ltr"><div dir="ltr"><div dir="ltr"><div class="gmail_quote"><div dir="ltr">On Thu, 20 Dec 2018 at 12:22, will wray via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></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 dir="ltr">Ah, so same issue for actual scalars as for scalar members of aggregates.<div><br></div><div>This bug prevents a port of my lib* to Clang, so I'd like to see it addressed.</div><div>There's no related bug report in Clang bugzilla AFAICT.</div><div><br></div><div>Shall I report?</div></div></div></blockquote><div><br></div><div>Should be fixed in r349820. (Our "extension" diagnostics should probably cause SFINAE failures by default, but for now I've just marked this particular one as doing so.)</div><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 dir="ltr"><div>Will</div><div><br></div><div><div>* The lib extends magic_get to support array type aggregate members</div><div> as described here <a href="https://github.com/apolukhin/magic_get/issues/20" target="_blank">https://github.com/apolukhin/magic_get/issues/20</a></div><div> - it relies on a sfinae / requires error to catch 'too-many-braces'.<br></div><div>This is a valuable niche use case, at least until static reflection arrives.</div><br class="gmail-m_1683302068156084974gmail-Apple-interchange-newline"></div><div>Oddly, the GCC bug that gives an error on single-brace-init of a scalar member</div><div>allows to discriminate a scalar member from an array-of-one-scalar member -</div><div>it seems a conforming implementation can't distinguish, say, int from int[1] -</div><div>but this ability comes at a cost of awkward non-uniform initialization syntax.</div></div></div></blockquote><div><br></div><div>Clang trunk accepts:</div><div><br></div><div><div>valid a = braces1<int[1]>(0);</div><div>valid b = braces2<int[1]>(0);</div><div>invalid c = braces3<int[1]>(0);</div><div><br></div><div>struct X { int n[1]; };</div><div>valid d = braces1<X>(0);</div><div>valid e = braces2<X>(0);</div><div>valid f = braces3<X>(0); </div></div><div><br></div><div>... which I believe is correct. (int[1] allows one more set of braces than int.)</div><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 class="gmail_quote"><div dir="ltr">On Thu, Dec 20, 2018 at 2:09 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></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 dir="ltr">[Adding back cfe-dev]<br><br><div class="gmail_quote"><div dir="ltr">On Wed, 19 Dec 2018 at 08:11, will wray <<a href="mailto:wjwray@gmail.com" target="_blank">wjwray@gmail.com</a>> wrote:<br></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 dir="ltr">Thanks, as ever, for your detailed explanation and for clarifying my question as C++ related.<div><br><div>Here's a Christmas tree (in concept): <a href="https://concept.godbolt.org/z/aFoGUL" target="_blank">https://concept.godbolt.org/z/aFoGUL</a><div><br></div><div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><div><font face="monospace, monospace"><span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">class</span> T> concept braces0 = requires { T{<span style="color:rgb(9,136,90)">0</span>}; };</font></div><div><font face="monospace, monospace"><span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">class</span> T> concept braces1 = requires { T{{<span style="color:rgb(9,136,90)">0</span>}}; };</font></div><div><font face="monospace, monospace"><span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">class</span> T> concept braces2 = requires { T{{{<span style="color:rgb(9,136,90)">0</span>}}}; };</font></div><div><font face="monospace, monospace"><span style="color:rgb(0,0,255)">template</span> <<span style="color:rgb(0,0,255)">class</span> T> concept braces3 = requires { T{{{{<span style="color:rgb(9,136,90)">0</span>}}}}; };</font></div><br></div></div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">So, for our class S with single scalar member we'd expect braces2<S> and on to evaluate false.</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">But Clang evaluates all as true - it doesn't catch the error in the expression (well, declaration statement)</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">in this unevaluated context (same in conventional sfinae attempts).</div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)"><br></div><div style="color:rgb(0,0,0);background-color:rgb(255,255,254)">Is this expected behaviour?</div></div></div></div></div></blockquote><div><br></div><div>No, that looks like a bug. Here's a testcase against clang trunk: <a href="https://gcc.godbolt.org/z/wLXqPD" target="_blank">https://gcc.godbolt.org/z/wLXqPD</a></div><div><br></div><div>ICC and MSVC get this right; GCC and Clang get it wrong in two different ways.</div><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 class="gmail_quote"><div dir="ltr">On Tue, Dec 18, 2018 at 8:35 PM Richard Smith <<a href="mailto:richard@metafoo.co.uk" target="_blank">richard@metafoo.co.uk</a>> wrote:<br></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 dir="ltr"><div dir="ltr"><div dir="ltr">(For clarity, since you didn't say, I'm assuming this is a question about C++, and I'm going to assume you mean Clang's default C++ mode, C++14.)<br><br><div class="gmail_quote"><div dir="ltr">On Tue, 18 Dec 2018 at 12:17, will wray via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a>> wrote:<br></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 dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><b><font face="monospace, monospace"> struct S { int i; };</font></b></div><div><b><font face="monospace, monospace"> S s{{0}};<br></font></b><br></div><div><b>Clang</b>: `<b>warning</b>: braces around scalar initializer [-Wbraced-scalar-init]`</div></div></div></div></div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>or, with more braces:</div></div></div></div></div></blockquote><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div> `<b>warning</b>: too many braces around scalar initializer [-Wmany-braces-around-scalar-init]<br>(consistent as a warning since at least clang 3.0.0)<br></div></div></div></div></div></blockquote><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><b>GCC</b>: `<b><font color="#ff0000">error</font></b>: braces around scalar initializer for type 'int'`</div><blockquote style="margin:0px 0px 0px 40px;border:none;padding:0px"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>(consistent as an error since ~gcc 4.4.7)</div></div></div></div></blockquote><div><b>MSVC</b>: no warning (with \Wall)<br></div><div><div><div><b>Intel</b>: warning #1119: extra braces are nonstandard<br></div></div><div><br></div><div>I believe that this is a non-standard extension in Clang. Can anyone confirm?</div></div></div></div></div></div></div></blockquote><div> </div><div>Nope, this is valid, and I'm frankly stunned that GCC rejects.</div><div><br></div><div>C++14 [dcl.init.aggr]/2 says: "Each member is copy-initialized from the corresponding initializer-clause. [...] [ Note: If an initializer-clause is itself an initializer list, the member is list-initialized, which will result in a recursive application of the rules in this section if the member is an aggregate. — end note ]"</div><div>C++14 [dcl.init.list]/3.5: "Otherwise, if the initializer list has a single element of type E and either T is not a reference type or its referenced type is reference-related to E, the object or reference is initialized from that element;"<br></div><div><br></div><div>In fact, it's valid in every revision of C++ since C++11. (It was ill-formed in C++98, which allowed int n = {0}, but not S s = {{0}};, but the syntax you used was added in C++11.)</div><div><br></div><div>The fact that clang accepts</div><div><br></div><div>struct S { int i; };</div><div>S s = {{0}};</div><div><br></div><div>in C++98 mode under -pedantic-errors is a (minor) bug.</div><div><br></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 dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div>Does the standard does mandate an error here?</div><div>If so then is there any flag to make this an error in Clang?</div><div><div><font face="monospace, monospace">(-pedantic-errors</font> flag makes no difference, for gcc or for clang.)</div>Maybe it's for MSVC / EDG compatibility? Or C compatibility? What reason?</div><div><br></div><div>An error allows compile-time code to distinguish between scalar and non-scalar,</div><div>to count the number of allowable braces and so to detect array rank & dims.</div><div><br></div><div>On the other hand, an error forces different syntax for initializing scalar and non-scalar</div><div>so disallows generic 'uniform' braced-init syntax where there may be scalars.</div><div><br></div><div>Thanks for any thoughts,</div><div>Will</div><div><br></div><div>Here are some issues/DRs & commits that may or may not be relevant<br></div><div>An old pre-11 issue</div><div><span style="color:rgb(0,0,0);font-family:"Times New Roman";font-size:medium">632. </span><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#632" style="font-family:"Times New Roman";font-size:medium" target="_blank">Brace-enclosed initializer for scalar member of aggregate</a><br>explains that this was a C/C++ incompatibility, says it was resolved by <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2008/n2672.htm" target="_blank">Initializer Lists</a></div><div>(LOL) (I can't see how or where it is resolved)</div></div></div></div></div></div></div></blockquote><div><br></div><div>See above.</div><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 dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div><div><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1501" target="_blank">h1501. Nested braces in list-initialization</a></div></div></div></div></div></div></div></blockquote><div><br></div><div>As noted here, one set of braces around a scalar initialization is permitted, and two or more sets is invalid. So:</div><div><br></div><div>S s = {{{0}}}; // error</div><div><br></div><div>and indeed for that Clang reports</div><div><br></div><div><div>error: too many braces around scalar initializer [-Werror,-Wmany-braces-around-scalar-init]</div><div>S s = {{{0}}};</div><div> ^~~</div></div><div><br></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 dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>As part of changes for <a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467" target="_blank">DR1467 List-initialization of aggregate from same-type object</a></div><div>this Clang commit<br><a href="http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20150209/123171.html" target="_blank">r228896 </a>- Improve the "braces around scalar init" warning to determine whether to warn</div></div></div></div></div></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div></div></div>
</blockquote></div>
</blockquote></div></div></div>
</blockquote></div>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div></div></div></div>