C++Talk.NET Forum Index C++Talk.NET
C++ language newsgroups
 
Archives   FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

VC7 disallowing definition of static const member for integr

 
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards
View previous topic :: View next topic  
Author Message
Tom Titchener
Guest





PostPosted: Wed Jan 12, 2005 7:15 pm    Post subject: VC7 disallowing definition of static const member for integr Reply with quote




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?

-------------------------------------------------------------------------------

// MyClass.h - test initialization of static const member variable

class MyClass

{

static const int num = 100;

public:

int GetNum() { return num; }

};

-------------------------------------------------------------------------------

// MyClass.cpp - test initialization of static const member variable

#include "stdafx.h"

#include "MyClass.h"

const int MyClass::num // <-- comment this out to link on VC7 !!

-------------------------------------------------------------------------------

// Test Compiler.cpp test initialization of static const member variable

#include "stdafx.h"

#include "MyClass.h"

using namespace std;

int main()

{

MyClass m;

cout << "m.num " << m.GetNum() << endl;

return 0;

}

-------------------------------------------------------------------------------

---
[ 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 ]

Back to top
Ron Natalie
Guest





PostPosted: Thu Jan 13, 2005 3:59 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote



Tom Titchener wrote:
Quote:
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 ]


Back to top
Alf P. Steinbach
Guest





PostPosted: Thu Jan 13, 2005 4:53 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote



* "Tom Titchener":
Quote:

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?

As Ron Natalie has noted, you cannot have multiple definitions.

But there is another issue here, and that's what's constitutes a multiple
definition.

For functions you can use "inline" to fold multiple source level definitions
into one.

For static data items you cannot do that, and that seems rather arbitrary;
and furthermore a static data item defined (i.e. initialized) in a class
definition is therefore not regarded as "inline" as defined member functions
are; it's nearly an inconsistency, and at the very least counter-intuitive.

After all, the compiler has to deal with that issue anyway, folding of static
data item definitions, because for static data items you can have multiple
source level definitions folded simply by using the template mechanism.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?

---
[ 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 ]


Back to top
dtmoore
Guest





PostPosted: Thu Jan 13, 2005 5:38 pm    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote

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.

HTH,

Dave Moore

---
[ 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 ]

Back to top
msalters
Guest





PostPosted: Thu Jan 13, 2005 5:38 pm    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote


Ron Natalie wrote:
Quote:
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.

Despite the wording of the original author, or the misleading error
message, the code has only one definition. The declararion in the
class has an initializer as per 9.4.2/4

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

Obviously, this is precisely what happens. There is exactly one TU
that has a definition of const int MyClass::num, it is at namespace
scope and it does not have an initializer. VC7 is wrong.
HTH,
Michiel Salters

---
[ 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 ]


Back to top
Tom Titchener
Guest





PostPosted: Fri Jan 14, 2005 1:57 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote


I agree it seems like a problem with VC7, especially as Scott Meyers tells
me the code in the sample compiles and links successfully with g++ 3.2 and
Comeau 4.3.3.

Thanks,

Tom Titchener

---
[ 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 ]

Back to top
Alberto Barbati
Guest





PostPosted: Fri Jan 14, 2005 2:21 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote

Ron Natalie wrote:
Quote:
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.


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

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

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

However, the "shall still be defined" strikes me, because I never
defined at namespace scope my initialized static const data members and
no compiler has ever complained... Just think about all those
BOOST_STATIC_CONSTANT out there! Where's the catch? Is "appearing in an
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 ]


Back to top
James Dennett
Guest





PostPosted: Fri Jan 14, 2005 5:02 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote

dtmoore wrote:
Quote:
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.

Quote:
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.)

Quote:
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 ]


Back to top
Dave Moore
Guest





PostPosted: Fri Jan 14, 2005 4:04 pm    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote

"James Dennett" <jdennett (AT) acm (DOT) org> wrote

Quote:
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.

Hmm .. it seems from other posts in this thread that perhaps the standard

does not in fact specify the behavior I described. However, that *is* how
specific compilers behave .. I only have access to g++ 3.3 and 3.4, and both
of them compile and link the OP's code both with and without the explicit
definition of num in the .cpp file. I guess the means I was putting the
cart before the horse ... I guess these compilers supply their own
definition when it is not supplied by the user, and this is *allowed* but
not *required* by the Standard.

Quote:
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.)

Ok, so maybe your latter point explains why the OP's example works in modern
compilers, even without the explicit definition in the .cpp file. (It also
explains the prohibition against in-class initialization of static const
members of aggregate type.) OTOH, it does not seem that omitting the
definition .

Anyway, thanks for the heads-up.

Dave Moore


---
[ 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 ]


Back to top
msalters
Guest





PostPosted: Fri Jan 14, 2005 4:05 pm    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote


Alberto Barbati wrote:
...
Quote:
§9.4.2/4 says

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

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

It will not be anymore Wink
Technically, you are right. The compilers could have complained, but
they didn't have to (no diagnostic req'd). However, since it was
observed that this definition is rather useless in the real world,
it has been proposed to relax the rules in the next standard.
The definition of "used in the program" will probably exclude
contexts in which the compiler should have made a compile-time
substitution.

However, there's one small detail...someone should come up with
the correct words. See Core issue 454, it's in draft.
Regards,
Michiel Salters


---
[ 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 ]


Back to top
Trevor L. Jackson, III
Guest





PostPosted: Sat Jan 15, 2005 6:10 am    Post subject: Re: VC7 disallowing definition of static const member for in Reply with quote

dtmoore wrote:
Quote:
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 ]


Back to top
Display posts from previous:   
Post new topic   Reply to topic    C++Talk.NET Forum Index -> C++ language, library and standards All times are GMT
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2006 phpBB Group
SEO toolkit © 2004-2006 webmedic.