Topic: VC7 disallowing definition of static const member for integral


Author: ron@sensor.com (Ron Natalie)
Date: Thu, 13 Jan 2005 03:59:48 GMT
Raw View
Tom Titchener wrote:
> When I compile and link the code below on VC7 (.net) I get the error:
>
> MyClass.obj : error LNK2005: "private: static int const MyClass::num"
> (?num@MyClass@@0HB) already defined in Test Compiler.obj
>
> If I comment-out the member definition, everything links and runs Ok.
>
> Does anybody know if the C++ standard says you *cannot* include a definition
> for static const members?  Or is this just a (very) minor quibble with VC7?

You can't have multiple definitions in C++, VC7 is certainly within its
rights to complain.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: AlbertoBarbati@libero.it (Alberto Barbati)
Date: Fri, 14 Jan 2005 02:21:01 GMT
Raw View
Ron Natalie wrote:
> Tom Titchener wrote:
>=20
>> When I compile and link the code below on VC7 (.net) I get the error:
>>
>> MyClass.obj : error LNK2005: "private: static int const MyClass::num"=20
>> (?num@MyClass@@0HB) already defined in Test Compiler.obj
>>
>> If I comment-out the member definition, everything links and runs Ok.
>>
>> Does anybody know if the C++ standard says you *cannot* include a=20
>> definition for static const members?  Or is this just a (very) minor=20
>> quibble with VC7?
>=20
>=20
> You can't have multiple definitions in C++, VC7 is certainly within its
> rights to complain.
>=20

No. The declaration of the static data member in the class definition=20
does not account for a definition even if it includes an initializer.=20
Precisely, =A79.4.2/4 says

"If a static data member is of const integral or const enumeration type,=20
its declaration in the class definition can specify a=20
constant-initializer which shall be an integral constant expression=20
(5.19). In that case, the member can appear in integral constant=20
expressions. The member shall still be defined in a namespace scope if=20
it is used in the program and the namespace scope definition shall not=20
contain an initializer."

So according to the standard the compiler should accept the code. Looks=20
like a VC7 bug to me.

However, the "shall still be defined" strikes me, because I never=20
defined at namespace scope my initialized static const data members and=20
no compiler has ever complained... Just think about all those=20
BOOST_STATIC_CONSTANT out there! Where's the catch? Is "appearing in an=20
integral constant expression" non considered to be a "use"?

Alberto

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: jdennett@acm.org (James Dennett)
Date: Fri, 14 Jan 2005 05:02:10 GMT
Raw View
dtmoore wrote:
> The point you are missing is that in-class initialization for *const*
> static data members of integral type implicitly provides a definition.

But that might safely be "missed", as it is not true -- but maybe I'm
wrong, in which case I'd be satisfied with a standards reference.

> The compiler makes sure that this implicit definition is only created
> once, no matter how many translation units the class declaration
> appears in.  Thus the second definition you supplied in the .cpp file
> is unnecessary and causes the link-error.

If the object's identity is needed, an explicit definition is required.
(If only its value is used, we can argue that no definition is needed.)

> Note that in-class initialization for data members of non-const
> integral type, or any flavor of aggregate type (const or not), is
> explicitly forbidden by the Standard.

True.

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]





Author: tlj3@comcast.net ("Trevor L. Jackson, III")
Date: Sat, 15 Jan 2005 06:10:32 GMT
Raw View
dtmoore wrote:
> The point you are missing is that in-class initialization for *const*
> static data members of integral type implicitly provides a definition.
> The compiler makes sure that this implicit definition is only created
> once, no matter how many translation units the class declaration
> appears in.  Thus the second definition you supplied in the .cpp file
> is unnecessary and causes the link-error.
>
> Note that in-class initialization for data members of non-const
> integral type, or any flavor of aggregate type (const or not), is
> explicitly forbidden by the Standard.

This is a useful test to distinguish C and C++ programs.  Eliminating
all of the const modifiers in a valid C program produces a valid C
program that yields the same result as the original program, possibly
less efficiently.  Eliminating all of the const modifiers in a C++
program produces something that is probably not a valid C++ program.

These inconsistencies are a very serious weakness in the language.  In
particular the lack of attention to the inadequacy of initialization in
all forms is particularly noteworthy.

/tj3

---
[ comp.std.c++ is moderated.  To submit articles, try just posting with ]
[ your news-reader.  If that fails, use mailto:std-c++@ncar.ucar.edu    ]
[              --- Please see the FAQ before posting. ---               ]
[ FAQ: http://www.jamesd.demon.co.uk/csc/faq.html                       ]