{"id":7331,"date":"2015-12-02T13:44:00","date_gmt":"2015-12-02T13:44:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vcblog\/2015\/12\/02\/constexpr-in-vs2015-update-1\/"},"modified":"2019-02-18T18:04:54","modified_gmt":"2019-02-18T18:04:54","slug":"constexpr-in-vs2015-update-1","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/cppblog\/constexpr-in-vs2015-update-1\/","title":{"rendered":"Constexpr in VS2015 Update 1"},"content":{"rendered":"<p>Visual Studio 2015 RTM shipped with support for <a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2015\/04\/29\/c-11-constant-expressions-in-visual-studio-2015-rc.aspx\">constant expressions<\/a> as specified in the C++11 language standard. The release received lots of excellent feedback from our users and the C++ community. Using that feedback, we&#8217;ve been working on refining our implementation for VS 2015 Update 1. Our goal with VS 2015 Update 1 was to finish up the last significant feature work for C++11 constexpr and improve our implementation&#8217;s robustness. This blog post is going to provide some notes to explain where VS 2015 Update 1 puts us&nbsp;and where we&#8217;re going with constexpr support.<\/p>\n<h2>Static Initializers<\/h2>\n<p>VS 2015 shipped with a warning that indicates that the compiler can detect and use initializers for constexpr evaluation but will not statically emit these initializers. That is, although the compiler had enough information to emit fully instantiated types that could be loaded from the compiled executable, it didn&#8217;t emit the fully instantiated types. These types were instantiated and constructed at runtime, as most C++ objects traditionally have been.<\/p>\n<p>The great news is that VS 2015 Update 1 now supports emitting static initializers! These types are fully instantiated when they&#8217;re loaded into memory, rather than running the code at runtime to initialize them. This was the last feature that we needed to implement for C++11 constexpr support and we&#8217;re excited to ship it with Update 1.<\/p>\n<p>We should extend kudos to Tanveer Gani for the herculean work he&#8217;s done to make this feature ship with Update 1. Because of his work, Update 1 will be shipping with complete support for emitting static initializers for constexpr objects. It will also ship with partial support for constant initialization of objects of non-literal types that have constexpr constructors (as specified in section 3.6.2 of the C++ language standard). Specifically, types with virtual functions aren&rsquo;t implemented yet.<\/p>\n<p>Static initializers are an important part of implementing <span style=\"font-family: courier new,courier\">std::once_flag<\/span>, which is used for <span style=\"font-family: courier new,courier\">std::call_once<\/span>. Stephan calls this out in his&nbsp;<a href=\"http:\/\/blogs.msdn.com\/b\/vcblog\/archive\/2015\/07\/14\/stl-fixes-in-vs-2015-part-2.aspx\">blog post<\/a>&nbsp;about improvements to the STL in VS 2015 RTM.<\/p>\n<p>The reduction in code generated by VS 2015 Update 1 for runtime execution can be quite dramatic. I&rsquo;d like to take some time to explore the behavior with some examples. The C++ source is shown first, followed by assembly code illustrating static initialization. The assembly for these code snippets was generated by invoking the C++ compiler with the <span style=\"font-family: courier new,courier\">\/FAsc<\/span> flag.<\/p>\n<h4>Example 1: Initialization of a Constexpr Object<\/h4>\n<p>We&rsquo;ll start with a simple example &ndash; constructing a simple instance of a type with a constexpr constructor.<\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">struct<\/span> Point {<\/span><br \/><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">&nbsp;&nbsp;&nbsp; constexpr<\/span> Point(int x1, int y1)<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp; : x(x1), y(y1)<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp; {}<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp; int x;<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp; int y;<\/span><br \/><span style=\"font-family: courier new,courier\">};<\/span><br \/><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">constexpr<\/span> Point p1(10, 11);<\/span><\/p>\n<p>First,&nbsp;the&nbsp;assembly generated by VS 2015 RTM&nbsp;for this snippet (for comparison):<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 RTM asm<\/span><br \/><span style=\"font-family: courier new,courier\">PUBLIC ??0Point@@QEAA@HH@Z&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; Point::Point<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">_BSS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?p1@@3UPoint@@B DQ 01H DUP (?)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; p1<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">_BSS&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDS<\/span><br \/><span style=\"font-family: courier new,courier\">text$di&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">??__Ep1@@YAXXZ PROC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; `dynamic initializer for &#8216;p1&#8221;, COMDAT<\/span><\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; 8&nbsp;&nbsp;&nbsp; : constexpr Point p1(10, 11);<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; sub&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsp, 40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; 00000028H<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; r8d, 11<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; edx, 10<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; lea&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rcx, OFFSET FLAT:?p1@@3UPoint@@B<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ??0Point@@QEAA@HH@Z <span style=\"color: #339966\">; Point::Point<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rsp, 40&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; 00000028H<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<\/span><br \/><span style=\"font-family: courier new,courier\">??__Ep1@@YAXXZ ENDP&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; `dynamic initializer for &#8216;p1&#8221;<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">text$di&nbsp; ENDS<\/span><\/p>\n<p>And now the assembly generated by VS 2015 Update 1:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?p1@@3UPoint@@B<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0aH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; p1<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0bH<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; ENDS<\/span><\/p>\n<p>Notice that there is no initialization code in the assembly generated by VS 2015 Update 1. Running the C++ code under the Visual Studio debugger in VS 2015 Update 1 will expectedly not execute the constructor for Point.<\/p>\n<h4>Example 2: Initialization of Array of Constexpr Objects<\/h4>\n<p>Continuing with the definition of Point above, we&rsquo;ll create an array of Points:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">constexpr<\/span> Point arr[] = { Point(2, 3), Point(5, 7), Point(11, 13) };<\/span><\/p>\n<p>The generated assembly from VS 2015 Update 1 is excellent:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?arr@@3QBUPoint@@B<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02H&nbsp; <span style=\"color: #339966\">; arr<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 03H<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 05H<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 07H<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0bH<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0dH<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; ENDS<\/span><\/p>\n<h4>&nbsp;Example 3: Initializing pointer and reference members of a constexpr object<\/h4>\n<p>This code snippet initializes a constexpr object with pointers and references to a global constexpr variable.<\/p>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">constexpr<\/span> int I = 42;<br \/><span style=\"color: #0000ff\">struct<\/span> A {<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">const<\/span> int&amp; ref;<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">const<\/span> char *ptr;<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">const<\/span> char *&amp;ref2;<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">constexpr<\/span> A(<span style=\"color: #0000ff\">const<\/span> char *p, <span style=\"color: #0000ff\">const<\/span> int&amp; r)<br \/>&nbsp;&nbsp;&nbsp; : ref(r), ptr(p), ref2{ptr}<br \/>&nbsp;&nbsp;&nbsp; {}<br \/>};<br \/><span style=\"color: #0000ff\">constexpr<\/span> A a{ \"qwerty\", I };<\/span><\/pre>\n<p>This sample actually causes an ICE in VS 2015 RTM, but generates&nbsp;delightfully terse assembly code in VS 2015 Update 1.<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?I@@3HB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02aH<\/span><br \/><span style=\"font-family: courier new,courier\">?a@@3UA@@B<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FLAT:?I@@3HB&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; a<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FLAT:$SG2668<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DD&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; FLAT:?a@@3UA@@B+4<\/span><br \/><span style=\"font-family: courier new,courier\">$SG2668<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;qwerty&#8217;, 00H<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; ENDS<\/span><\/p>\n<h4>Example 4: Initializing constexpr classes with base constructors<\/h4>\n<p>Even classes with complicated (non-virtual) inheritance can be initialized statically. I&rsquo;m not going to list the VS 2015 RTM as it&rsquo;s prohibitively long, but you can view the COD file yourself by compiling the snippet below with the <span style=\"font-family: courier new,courier\">\/FAsc<\/span> flag.<\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">struct<\/span> Empty {};<br \/><span style=\"color: #0000ff\">struct<\/span> A {<br \/>&nbsp;&nbsp;&nbsp;&nbsp; short i;<br \/>&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">constexpr<\/span> A(int ii)<br \/>&nbsp;&nbsp;&nbsp;&nbsp; : i(ii)<br \/>&nbsp;&nbsp;&nbsp;&nbsp; {}<br \/>};<br \/><span style=\"color: #0000ff\">struct<\/span> B {<br \/>&nbsp;&nbsp;&nbsp; double d;<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">constexpr<\/span> B(double di)<br \/>&nbsp;&nbsp;&nbsp; : d(di)<br \/>&nbsp;&nbsp;&nbsp; {}<br \/>};<br \/><span style=\"color: #0000ff\">struct<\/span> C : Empty, A, B {<br \/>&nbsp;&nbsp;&nbsp; double x;<br \/>&nbsp;&nbsp;&nbsp; <span style=\"color: #0000ff\">constexpr<\/span> C()<br \/>&nbsp;&nbsp;&nbsp; : x(1.0), A(42), B(-1.0)<br \/>&nbsp;&nbsp;&nbsp; {}<br \/>};<br \/><span style=\"color: #0000ff\">constexpr<\/span> C c;<br \/><\/span><\/span><\/p>\n<p>And the assembly generated by VS 2015 Update 1:<\/p>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?c@@3UC@@B DW&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 02aH&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; c<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ORG $+6<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0bff0000000000000r&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; -1<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 03ff0000000000000r&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; 1<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; ENDS&nbsp;<\/span><\/pre>\n<h4>&nbsp;Example 5: Initializing a non-literal type<\/h4>\n<p>As mentioned above, some non-literal types that are initialized with constants can be statically initialized. In the sample below, the initialized supplied to the constexpr constructor is a constant, so Update 1 can statically initialize it. Note that the type has a destructor, which makes the type a non-literal type.<\/p>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">extern<\/span> <span style=\"color: #a31515\">\"C\"<\/span> <span style=\"color: #2b91af\">int<\/span> puts(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #2b91af\">char<\/span>*);<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">struct<\/span> NonLiteralType {<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">const<\/span> <span style=\"color: #2b91af\">char<\/span> *p;<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #0000ff\">constexpr<\/span> NonLiteralType(<span style=\"color: #0000ff\">const<\/span> <span style=\"color: #2b91af\">char<\/span> *pp)<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">: p(pp)<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">{}<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\">&nbsp;<\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">~NonLiteralType() {<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 90px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">puts(<span style=\"color: #a31515\">\"~NonLiteralType()\"<\/span>);<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 60px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">}<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">};<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\">NonLiteralType nlt(<span style=\"color: #a31515\">\"qwerty\"<\/span>);<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;padding-left: 30px;font-style: normal;font-variant: normal;font-weight: normal\"><span style=\"font-family: courier new,courier\"><span style=\"color: #2b91af\">int<\/span> main(){}<\/span><\/pre>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;font-style: normal;font-variant: normal;font-weight: normal\">&nbsp;<\/pre>\n<p style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;font-style: normal;font-variant: normal;font-weight: normal\">The assembly generated in Update 1 does not place the object in the CONST segment, because it was not declared constexpr:<\/p>\n<pre style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;font-style: normal;font-variant: normal;font-weight: normal\">&nbsp;<\/pre>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">$SG2669&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; DB&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &#8216;qwerty&#8217;, 00H<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; ENDS<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">_DATA&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?nlt@@3UNonLiteralType@@A DD FLAT:$SG2669&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; nlt<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">_DATA&nbsp; ENDS<\/span><\/p>\n<p style=\"margin: 0px;color: #333333;line-height: 16.25px;text-indent: 0px;letter-spacing: normal;font-style: normal;font-variant: normal;font-weight: normal\">Destruction of the non-literal type object is done with a registered &ldquo;atexit&rdquo; function:<\/p>\n<p style=\"padding-left: 30px\"><span style=\"color: #339966;font-family: courier new,courier\">; VS 2015 Update 1 asm<\/span><br \/><span style=\"font-family: courier new,courier\">CRT$XCU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">?nlt$initializer$@@3P6AXXZA DD FLAT:??__Fnlt@@YAXXZ <span style=\"color: #339966\">; nlt$initializer$<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">CRT$XCU&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ENDS<\/span><br \/><span style=\"font-family: courier new,courier\">CONST&nbsp; SEGMENT<\/span><\/p>\n<p style=\"padding-left: 30px\"><span style=\"font-family: courier new,courier\">text$yd SEGMENT<\/span><br \/><span style=\"font-family: courier new,courier\">??__Fnlt@@YAXXZ<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; PROC <span style=\"color: #339966\">; `dynamic atexit destructor for &#8216;nlt&#8221;, COMDAT<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; push&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp, esp<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mov&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ecx, OFFSET ?nlt@@3UNonLiteralType@@A&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <span style=\"color: #339966\">; nlt<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; call&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ??1NonLiteralType@@QAE@XZ <span style=\"color: #339966\">; NonLiteralType::~NonLiteralType<\/span><\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pop&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ebp<\/span><br \/><span style=\"font-family: courier new,courier\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ret&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<\/span><br \/><span style=\"font-family: courier new,courier\">??__Fnlt@@YAXXZ ENDP ; `dynamic atexit destructor for &#8216;nlt&#8221;<\/span><br \/><span style=\"font-family: courier new,courier\">text$yd ENDS<\/span><\/p>\n<h2>Quality Improvements<\/h2>\n<p>Alongside the static initializer work, we&#8217;ve fixed ~45 bugs related to constexpr usage. The majority of these bugs were reported to us by customers. Because we tried to prioritize customer issues, you should see improvements across the board when writing constexpr code rather than in any particular areas. The table below shows the bugs that we fixed. Thanks to everybody who filed bugs!<\/p>\n<table>\n<tbody>\n<tr>\n<td><strong>Title<\/strong><\/td>\n<td><strong>Connect Customer<\/strong><\/td>\n<td><strong>ConnectID<\/strong><\/td>\n<\/tr>\n<tr>\n<td>[constexpr] Using final on the member variable&#8217;s class breaks constexpr<\/td>\n<td>Aepaerae<\/td>\n<td>1135313<\/td>\n<\/tr>\n<tr>\n<td>Error C2131 when creating constexpr std::array<\/td>\n<td>Andrey Ashikhmin<\/td>\n<td>1574634<\/td>\n<\/tr>\n<tr>\n<td>constexpr void pointer variables not treated as constants<\/td>\n<td>anthonyw1<\/td>\n<td>1609590<\/td>\n<\/tr>\n<tr>\n<td>constexpr failure with std::array<\/td>\n<td>Brandon Kentel<\/td>\n<td>1604956<\/td>\n<\/tr>\n<tr>\n<td>Constexpr causes Internal Compiler Error<\/td>\n<td>camhusmj38<\/td>\n<td>1573435<\/td>\n<\/tr>\n<tr>\n<td>Constexpr causes Internal Compiler Error<\/td>\n<td>camhusmj38<\/td>\n<td>1570534<\/td>\n<\/tr>\n<tr>\n<td>Constexpr produces wrong results [compared to LLVM]<\/td>\n<td>camhusmj38<\/td>\n<td>1300591<\/td>\n<\/tr>\n<tr>\n<td>Erroneous error C2131: expression did not evaluate to a constant<\/td>\n<td>camhusmj38<\/td>\n<td>1596224<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 believes constexpr member pointer is not constant<\/td>\n<td>David Majnemer<\/td>\n<td>1327934<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 crashes on pointer arithmetic in constexpr context<\/td>\n<td>David Majnemer<\/td>\n<td>1420558<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 crashes trying to evaluate constexpr constructor<br \/>which initializes a reference<\/td>\n<td>David Majnemer<\/td>\n<td>1404631<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 crashes trying to evaluate constexpr containing pointer to member function<\/td>\n<td>David Majnemer<\/td>\n<td>1327996<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 incorrectly rejects constexpr array of unions access<\/td>\n<td>David Majnemer<\/td>\n<td>1323869<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 incorrectly rejects pointer equality in constexpr context<\/td>\n<td>David Majnemer<\/td>\n<td>1404624<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 materializes one constant instead of two in constexpr context<\/td>\n<td>David Majnemer<\/td>\n<td>1404688<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 rejects initializing constexpr reference to temporary object<\/td>\n<td>David Majnemer<\/td>\n<td>1404715<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 rejects lvalue conditional operator of type const int in constexpr context<\/td>\n<td>David Majnemer<\/td>\n<td>1404674<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 rejects member pointer comparison in constexpr context<\/td>\n<td>David Majnemer<\/td>\n<td>1401241<\/td>\n<\/tr>\n<tr>\n<td>MSVC2015 rejects valid and accepts invalid constexpr static_cast<\/td>\n<td>David Majnemer<\/td>\n<td>1330530<\/td>\n<\/tr>\n<tr>\n<td>MSVC 2015 will not evaluate function-local static constexpr reference variable to<br \/>temporary<\/td>\n<td>David Majnemer<\/td>\n<td>1404755<\/td>\n<\/tr>\n<tr>\n<td>Failure to compile with valid use of &#8216;constexpr&#8217;<\/td>\n<td>dn357<\/td>\n<td>1311469<\/td>\n<\/tr>\n<tr>\n<td>Compiller Failiure in constexpr statement on std::make_array proposal implementation<\/td>\n<td>Felix Petriconi<\/td>\n<td>1494444<\/td>\n<\/tr>\n<tr>\n<td>`std::integral_constant&lt;&gt;` implicitly-defined default constructor and\/or `operator value_type` not<br \/>constexpr<\/td>\n<td>ildjarn<\/td>\n<td>1497236<\/td>\n<\/tr>\n<tr>\n<td>Bogus error regarding returning the address of or a reference to a temporary when attempting aggregate initialization inside of a constexpr function<\/td>\n<td>ildjarn<\/td>\n<td>1498733<\/td>\n<\/tr>\n<tr>\n<td>C++ &ndash; constexpr does not work with aggregate initialization<\/td>\n<td>ildjarn<\/td>\n<td>1572056<\/td>\n<\/tr>\n<tr>\n<td>C++ &ndash; constexpr does not work with delegating constructors<\/td>\n<td>ildjarn<\/td>\n<td>1579279<\/td>\n<\/tr>\n<tr>\n<td>C++ &ndash; constexpr static member functions must be fully qualified when called during type definition<\/td>\n<td>ildjarn<\/td>\n<td>1579334<\/td>\n<\/tr>\n<tr>\n<td>C++ &ndash; Internal compiler error with constexpr constructor<\/td>\n<td>ildjarn<\/td>\n<td>1571950<\/td>\n<\/tr>\n<tr>\n<td>[constexpr] bug in deducing constexpr of function pointer<\/td>\n<td>koosw<\/td>\n<td>1378031<\/td>\n<\/tr>\n<tr>\n<td>Failed in constexpr lambda workaround<\/td>\n<td>mzer0<\/td>\n<td>1673865<\/td>\n<\/tr>\n<tr>\n<td>VC++2015 RTM &#8211; constexpr constructor errors with union members with bitfields<\/td>\n<td>Orvid King<\/td>\n<td>1571281<\/td>\n<\/tr>\n<tr>\n<td>constexpr and recurring template cause fatal error C1001<\/td>\n<td>Pendenaor<\/td>\n<td>1711144<\/td>\n<\/tr>\n<tr>\n<td>class static constexpr value is 0<\/td>\n<td>pmingkr<\/td>\n<td>1384724<\/td>\n<\/tr>\n<tr>\n<td>constexpr delegating constructor doesn&#8217;t compile<\/td>\n<td>Quixotic Labs<\/td>\n<td>1229998<\/td>\n<\/tr>\n<tr>\n<td>constexpr bug related to &#8220;char const*const&#8221; parameters<\/td>\n<td>Rui Figueira (Cloudgine)<\/td>\n<td>1272743<\/td>\n<\/tr>\n<tr>\n<td>[constexpr][regression][boost] VC++ internal compiler error for a non-type template instantiation<\/td>\n<td>Sasha Sitnikov<\/td>\n<td>1577162<\/td>\n<\/tr>\n<tr>\n<td>delegating constructor in constexpr ctor won&#8217;t compile<\/td>\n<td>submitting_bug_reports_is_too_damn_hard<\/td>\n<td>1463556<\/td>\n<\/tr>\n<tr>\n<td>[Feedback] ICE when compiling this C\/C++ code<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>Bogus error C2131 &#8220;expression did not evaluate to a constant&#8221; triggered by variadic-recursive constexpr<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>constexpr delegating constructors<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>constexpr template function causes compilation failure with erroneous message when called from within struct template<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<tr>\n<td>constexpr 4607 ICE triggered by &#8220;ptr ? 3 : 4&#8221; in a constexpr function<\/td>\n<td>&nbsp;<\/td>\n<td>&nbsp;<\/td>\n<\/tr>\n<\/tbody>\n<\/table>\n<h2>Looking Forward<\/h2>\n<p>Even with the improvements to C++11 constexpr that are shipping with update 1, we still have some refinement to do on our implementation. There are ~30 bugs remaining on our backlog in this area, many related to pointers-to-members in constant expressions. There&#8217;s some quality work to do around array and string aliasing, and although Tanveer&#8217;s done a solid job of readying static initializers, we&#8217;re planning for some amount of incoming bug reports related to the change.<\/p>\n<p>Essentially, all of this means that we&#8217;ll still be working on C++11 constexpr for a while longer, but the outstanding work is manageable. Our goal is to wrap this work up in time for the next Visual Studio update. The plan after that is to immediately dive into C++14 constexpr support.<\/p>\n<p>&nbsp;<\/p>\n<p>Cody Miller<\/p>\n<p>Visual C++ Team<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Visual Studio 2015 RTM shipped with support for constant expressions as specified in the C++11 language standard. The release received lots of excellent feedback from our users and the C++ community. Using that feedback, we&#8217;ve been working on refining our implementation for VS 2015 Update 1. Our goal with VS 2015 Update 1 was to [&hellip;]<\/p>\n","protected":false},"author":314,"featured_media":35994,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[1],"tags":[],"class_list":["post-7331","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cplusplus"],"acf":[],"blog_post_summary":"<p>Visual Studio 2015 RTM shipped with support for constant expressions as specified in the C++11 language standard. The release received lots of excellent feedback from our users and the C++ community. Using that feedback, we&#8217;ve been working on refining our implementation for VS 2015 Update 1. Our goal with VS 2015 Update 1 was to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7331","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/users\/314"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/comments?post=7331"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/posts\/7331\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media\/35994"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/media?parent=7331"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/categories?post=7331"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/cppblog\/wp-json\/wp\/v2\/tags?post=7331"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}