Initializing const members of structs in C/C++... compiler dependent?
<p>Recently I ran into a compiler error in a legacy environment using Borland C++ 5.2. I had a .cpp file which included a header from some C source which I don't control.  The header contained a struct definition which included const members, and the compiler complained about a "constant member in class without constructors". On investigation, this error seems to be compiler-dependent. Here's some sample code w/ results from various compilers:</p>

<pre><code>#include &lt;stdio.h&gt;

typedef struct {
   const float a;
} _floater;

int main()
{
   _floater f = {5.1F};

   printf("%f\r\n",f.a);

   return 0;
}
</code></pre>

<p><strong>Borland 5.2</strong></p>



<pre class="none prettyprint-override"><code>E:\Projects\Scratchpad&gt;bcc32 -P const_float.c
Borland C++ 5.2 for Win32 Copyright (c) 1993, 1997 Borland International
const_float.c:
Error const_float.c 13: Constant member ' ::a' in class without constructors
*** 1 errors in Compile ***
</code></pre>

<p><strong>Microsoft VS 2003 .NET:</strong></p>

<pre class="none prettyprint-override"><code>E:\Projects\Scratchpad&gt;cl /TP const_float.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 12.00.8804 for 80x86
Copyright (C) Microsoft Corp 1984-1998. All rights reserved.

const_float.c
const_float.c(19) : error C2552: 'f' : non-aggregates cannot be initialized with
initializer list
</code></pre>

<p><strong>Microsoft VS 2008:</strong></p>

<pre class="none prettyprint-override"><code>C:\Projects\Scratchpad&gt;cl /TP const_float.c
Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 15.00.21022.08 for 80x86
Copyright (C) Microsoft Corporation.  All rights reserved.

const_float.c
Microsoft (R) Incremental Linker Version 9.00.21022.08
Copyright (C) Microsoft Corporation.  All rights reserved.

/out:const_float.exe
const_float.obj

C:\Projects\Scratchpad&gt;const_float.exe
5.100000
</code></pre>

<p><strong>G++ 3.3.3</strong></p>

<pre class="none prettyprint-override"><code>$ g++ const_float.c -o const_float.exe
const_float.c:25:2: warning: no newline at end of file

$ ./const_float.exe
5.100000
</code></pre>

<p>Note that Borland fails at the declaration of the struct, because it has a const member but no constructors, while VS 2003 is ok w/ the declaration, but complains when you try to instantiate it with an initializer list – considering the struct a non-aggregate type.  VS2008 and g++ are perfectly happy.
[Apologies.. I just realized that the line #s in the errors are wrong because I stripped some commented-out lines before posting.]</p>

<p>Microsoft’s definition of aggregates is here: <a href="http://msdn.microsoft.com/en-us/library/0s6730bb.aspx" rel="nofollow">http://msdn.microsoft.com/en-us/library/0s6730bb.aspx</a>. It’s not apparent to me that const members would make a struct non-aggregate, but maybe they did back in 2003.</p>

<p>It also appears that the latest Borland (Embarcadero) compiler treats this as a warning rather than an error: <a href="http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/wrnmembnocons_xml.html" rel="nofollow">http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devwin32/wrnmembnocons_xml.html</a> .</p>

<p>So, 2 questions I guess:</p>

<ol>
<li>Why the variance in compilers? Is the standard ambiguous on this point?</li>
<li>Any workarounds? Given that I'm stuck w/ the compiler version and the header file, I don't see any.</li>
</ol>

<p>Thanks!</p>
