<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jan 22, 2014 at 11:22 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:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><br><div><div class="im">
<div>On Jan 21, 2014, at 5:59 AM, Rahul Jain <<a href="mailto:rahul1.jain@samsung.com" target="_blank">rahul1.jain@samsung.com</a>> wrote:</div><br><blockquote type="cite"><div style="font-size:9pt;font-family:Arial,arial;margin:10px;line-height:1.4;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px"> <br></div><p style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px">Hi all,</p><div style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px">
<br></div><div>Note - this is with respect to C++ 03.</div><div></div><div><em></em> </div><div><em>Test code:</em></div><div><em></em> </div><div><em>template <int> struct A {};<br>int const i = {42};<br>typedef A<i> Ai;</em></div>
</div></blockquote><div><br></div></div>Short, snarky answer - you can’t bracket-initialize a variable in c++03</div></div></blockquote><div><br></div><div>You can in a few cases: specifically, if the type is an aggregate or a scalar type. In the latter case,</div>
<div><br></div><div> T x = { a };</div><div><br></div><div>is equivalent to</div><div><br></div><div> T x = a;</div><div><br></div><div>(See C++03 [dcl.init](8.5)/13.)</div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><div class="im"><div><span style="white-space:pre-wrap"> </span>int const i = {42};</div><div><br></div></div><div class="im"><div><blockquote type="cite"><div style="font-size:9pt;font-family:Arial,arial;margin:10px;line-height:1.4;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div>For non-type template argument, standard (C++ 03) says that:</div><div></div><div><em>14.3.2 / 1</em></div><p style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px"><em>A template-argument for a non-type, non-template template-parameter shall be one of:</em></p>
<ul><em></em><li style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px"><em>an<span> </span><strong>integral constant-expression</strong><span> </span>of integral or enumeration type; or ......</em></li>
</ul><div>For the test code above, the statement '<em>typedef A<i> Ai</em>', should the compiler</div><div>check the rhs (rvalue) of variable 'i' to determine if it is a constant or not?</div></div></blockquote>
</div></div></div></blockquote><div><br></div><div>Yes. For 'i' to be an integral constant-expression, it can only mention "const variables [...] of integral or enumeration types initialized with constant expressions" (C++03 [expr.const](5.19)/1). So the compiler is required to check whether 'i' is indeed initialized by a constant expression.</div>
<div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div style="word-wrap:break-word"><div class="im">
<div><blockquote type="cite"><div style="font-size:9pt;font-family:Arial,arial;margin:10px;line-height:1.4;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div>Shouldnt it just check the type of i (which is declared as const)?</div><div>Whether 'i' evaluates to constant (at compile time) or not should be the responsibility of compiler</div><div>while processing statement '<em>int const i = {42}</em>' and not '<em>typedef A<i> Ai' ? Isnt it?</em></div>
<div> </div><div>Another analogy:<br>For arrays, the size of the array needs to be a compile time constant. So, the following code :</div><div></div><div><em></em> </div><div><em>int const x = 42;</em></div><div><em>int z[x];</em></div>
<div></div><div> </div><div>For the statement<span> </span><em>'int z[x]'</em>, will the compiler evaluate the rhs of<span> </span><em>'x'</em><span> </span>to check if it evaluates to constant at runtime</div>
<div>or will it just see that '<em>x</em>' is of 'integer const' type and hence there is no problem with the array declaration?</div><div>Whether '<em>x</em>' evaluates to constant should be the responsibility of compiler while processing statement '<em>int const x=42</em>'</div>
<div>and not while processing '<em>int z[x]</em>' ?</div><div></div><div> </div><div>Should this analogy be applicable to non-type template argument?</div></div></blockquote></div></div></div></blockquote><div><br>
</div><div>According to the C++ standard, the two cases are exactly the same. However, to support code relying on GCC extensions, we allow any constant-foldable expression as an array bound, whereas we require a constant-expression as a template argument. Use -pedantic-errors to enable Clang's strictly-conforming mode, where we (incorrectly) reject both cases.</div>
<div><br></div><div>The bug is that CheckICE in lib/AST/ExprConstant.cpp (or maybe VarDecl::checkInitIsICE) doesn't handle the case of an InitListExpr being used to initialize a scalar.</div><div><br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div style="word-wrap:break-word"><div class="im"><div><blockquote type="cite"><div style="font-size:9pt;font-family:Arial,arial;margin:10px;line-height:1.4;font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">
<div></div><p style="margin-bottom:5px;font-size:9pt;font-family:Arial,arial;margin-top:5px">Please throw some light on this, am I missing any particular case?</p></div></blockquote><br></div></div><div>My understanding (which may be flawed) is that the compiler needs to see both:</div>
<div>* That the compiler needs to be able to determine that the value it needs is const</div><div>* That the compiler can see what the value actually is, so that it can allocate space for the array, or instantiate the template.</div>
<div><br></div><div><br></div><div>So, this would not work:</div><div><br></div><span style="white-space:pre-wrap"> </span>extern const int i;<div><span style="white-space:pre-wrap"> </span>template <int> struct A {};<br>
<span style="white-space:pre-wrap"> </span>typedef A<i> Ai;</div></div></blockquote><div><br></div><div>Right. </div></div></div></div>