473,549 Members | 2,346 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

static const variables

I'm reading the comp.lang.c++ faq and, though it is incredibly clear and
lucid in many points, I am completely confused by question 29.6:

http://www.parashift.com/c++-faq-lit....html#faq-29.6
"Here is another even more common example:

class Fred {
public:
...
private:
static const int max_ = 107;
...
};
In this example, you would need to add the line int Fred::max_; in exactly
one .cpp file, typically in Fred.cpp."

Firstly, shouldn't it say "const int Fred::max_"?
Secondly, it indicates the following code is correct (modulo the _tmain and
tchar nonsense):

//foo.cpp
#include "jimmy.h"
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[]) {
while(jimmy::fo o==5);
return 0;
}

//jimmy.h
class jimmy {
public:
static const int foo=5;
};

//jimmy.cpp
#include "jimmy.h"
const int jimmy::foo;
This code fails to compile under MSVC++, with the following output:

Compiling...
foo.cpp

Linking...

foo.obj : error LNK2005: "public: static int const jimmy::foo"
(?foo@jimmy@@2H B) already defined in jimmy.obj

Is the compiler misbehaving? Or is the FAQ misleading? Or am I just
confused?

When I remove the line "const int jimmy::foo;" from jimmy.cpp it compiles
fine under MSVC++; and if I also replace _tmain() with main(), and TCHAR
with char and so on, it compiles fine with "g++ -W -Wall -ansi -pedantic
*.cpp -ofoo". If I am supposed to be defining this static variable in one
compilation unit, g++ isn't detecting this as non-standard C++.

I can't find any reference to this in TC++PL, 3rd Ed, to clarify my
confusion. I've tried checking the index under "static member" and no
mention is made of the need to define static members in exactly one
compilation unit.

What's going on? Do I have to define it or not?

Philip
Jul 26 '06 #1
12 2878
Philip Potter wrote:
I'm reading the comp.lang.c++ faq and, though it is incredibly clear
and lucid in many points, I am completely confused by question 29.6:

http://www.parashift.com/c++-faq-lit....html#faq-29.6
"Here is another even more common example:

class Fred {
public:
...
private:
static const int max_ = 107;
...
};
In this example, you would need to add the line int Fred::max_; in
exactly one .cpp file, typically in Fred.cpp."

Firstly, shouldn't it say "const int Fred::max_"?
Yes, and Marshall will hopefully notice that and correct it.
Secondly, it indicates the following code is correct (modulo the
_tmain and tchar nonsense):

//foo.cpp
#include "jimmy.h"
#include <tchar.h>

int _tmain(int argc, _TCHAR* argv[]) {
while(jimmy::fo o==5);
return 0;
}

//jimmy.h
class jimmy {
public:
static const int foo=5;
};

//jimmy.cpp
#include "jimmy.h"
const int jimmy::foo;
This code fails to compile under MSVC++, with the following output:

Compiling...
foo.cpp

Linking...

foo.obj : error LNK2005: "public: static int const jimmy::foo"
(?foo@jimmy@@2H B) already defined in jimmy.obj

Is the compiler misbehaving? Or is the FAQ misleading? Or am I just
confused?
The compier is misbehaving. The Standard requires following the ODR
and the program does just that.
When I remove the line "const int jimmy::foo;" from jimmy.cpp it
compiles fine under MSVC++; and if I also replace _tmain() with
main(), and TCHAR with char and so on, it compiles fine with "g++ -W
-Wall -ansi -pedantic *.cpp -ofoo". If I am supposed to be defining
this static variable in one compilation unit, g++ isn't detecting
this as non-standard C++.
There is a proposal on the table that makes it unnecessary to define
a static integral constant *unless* its address is taken. Your program
should be valid in either case.
I can't find any reference to this in TC++PL, 3rd Ed, to clarify my
confusion. I've tried checking the index under "static member" and no
mention is made of the need to define static members in exactly one
compilation unit.

What's going on? Do I have to define it or not?
You do, as of now, to be fully standard-compliant. However, you do
not, with many implementations today, who are (in this regard) running
ahead of the standardisation process.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 26 '06 #2

"Victor Bazarov" <v.********@com Acast.netwrote in message
news:ea******** **@news.datemas .de...
Philip Potter wrote:
>In this example, you would need to add the line int Fred::max_; in
exactly one .cpp file, typically in Fred.cpp."

Firstly, shouldn't it say "const int Fred::max_"?

Yes, and Marshall will hopefully notice that and correct it.
>>
//jimmy.h
class jimmy {
public:
static const int foo=5;
};

//jimmy.cpp
#include "jimmy.h"
const int jimmy::foo;

Victor (et al): doesn't the standard require that the member be initialized
at the point of definition, not the point of declaration? Every time I've
seen or used a static const member, the initialization is in the
implementation code, not in the class definition. I thought this was a
requirement. (But hey, I've been wrong once or twice before. This morning,
in fact.)

Also, could the lack of include guards be affecting the linking here?

-Howard


Jul 26 '06 #3
Howard wrote:
[..]
Victor (et al): doesn't the standard require that the member be
initialized at the point of definition, not the point of declaration?
It allows static constants of integral type to be initialised in the
class definition. (too lazy to look up the paragraph)
Every time I've seen or used a static const member, the
initialization is in the implementation code, not in the class
definition. I thought this was a requirement. (But hey, I've been
wrong once or twice before. This morning, in fact.)

Also, could the lack of include guards be affecting the linking here?
I don't think so. Double inclusion guards need to protect from multiple
definitions when including the same header in the *same* TU more than
once (usually through other headers). It's not the case here.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 26 '06 #4

"Victor Bazarov" <v.********@com Acast.netwrote in message
news:ea******** **@news.datemas .de...
Howard wrote:
>[..]
Victor (et al): doesn't the standard require that the member be
initialized at the point of definition, not the point of declaration?

It allows static constants of integral type to be initialised in the
class definition. (too lazy to look up the paragraph)
Yes, but the post had the initialization in the class definition, and ALSO
had a definition (without initialization) in the implementation file. When
initializing in the class definition, is it ok and/or normal to also put a
definition in the implementation file?

The OP had this:

//jimmy.h
class jimmy {
public:
static const int foo=5;
};

//jimmy.cpp
#include "jimmy.h"
const int jimmy::foo;

I'm thinking either of the following would fix things:

//jimmy.h
class jimmy {
public:
static const int foo;
};

//jimmy.cpp
#include "jimmy.h"
const int jimmy::foo=5;

....or...

//jimmy.h
class jimmy {
public:
static const int foo=5;
};

//jimmy.cpp
#include "jimmy.h"

-Howard
Jul 26 '06 #5
Howard wrote:
"Victor Bazarov" <v.********@com Acast.netwrote in message
news:ea******** **@news.datemas .de...
>Howard wrote:
>>[..]
Victor (et al): doesn't the standard require that the member be
initialized at the point of definition, not the point of
declaration ?

It allows static constants of integral type to be initialised in the
class definition. (too lazy to look up the paragraph)

Yes, but the post had the initialization in the class definition, and
ALSO had a definition (without initialization) in the implementation
file. When initializing in the class definition, is it ok and/or
normal to also put a definition in the implementation file?
Not only it's OK. It's *required* by the current Standard.

Please don't make me leaf through the Standard. Get yourself a copy
and find the exact wording, and then read the archives about the new
proposal that makes it unnecessary to define the static const integral
member if it's not used as an lvalue.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask
Jul 26 '06 #6
Victor Bazarov wrote:
Howard wrote:
>[..]
Victor (et al): doesn't the standard require that the member be
initialized at the point of definition, not the point of declaration?

It allows static constants of integral type to be initialised in the
class definition. (too lazy to look up the paragraph)
9.4.2/4

Just had to look that up yesterday to beat someone over the head with :)
They were trying to inline initialize a static const double.
Jul 26 '06 #7
Philip Potter posted:
foo.obj : error LNK2005: "public: static int const jimmy::foo"
(?foo@jimmy@@2H B) already defined in jimmy.obj

Your compiler/linker/whatever is Microsoftsque.
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. 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.

--

Frederick Gotham
Jul 26 '06 #8
Howard wrote:
...
Yes, but the post had the initialization in the class definition, and ALSO
had a definition (without initialization) in the implementation file. When
initializing in the class definition, is it ok and/or normal to also put a
definition in the implementation file?
...
Yes, the language (as described in C++98) makes an exception for static const
members of integral and enum types - they can be supplied with an initializer in
the class definition. Note, that presence of the initializer does not turn the
declaration of such a member into a definition, meaning that the separate
definition (without an initializer) is still required. (The updated standard
made (TC1?) some updates to that specification, as Victor already mentioned.)

In other words, the user can choose where to put the initializer for static
const member of integral or enum type. One important detail here is that when
the initializer is supplied in the class definition, the const member can be
used as an integral constant expression (ICE) everywhere in the program. When
the initializer is supplied at the point of member definition, it might only be
used as an ICE in that translation unit where it is defined, and it is not an
ICE anywhere else.

The practice to put the initializer at the point of member definition was/is
popular because certain compilers refused to accept initializers in class
definition.

--
Best regards,
Andrey Tarasevich
Jul 26 '06 #9
"Victor Bazarov" <v.********@com Acast.netwrote in message
news:ea******** **@news.datemas .de...
Philip Potter wrote:
Is the compiler misbehaving? Or is the FAQ misleading? Or am I just
confused?

The compier is misbehaving. The Standard requires following the ODR
and the program does just that.
Thank you very much for a clear response! It seems like an ugly language
feature. What is the ODR?
When I remove the line "const int jimmy::foo;" from jimmy.cpp it
compiles fine under MSVC++; and if I also replace _tmain() with
main(), and TCHAR with char and so on, it compiles fine with "g++ -W
-Wall -ansi -pedantic *.cpp -ofoo". If I am supposed to be defining
this static variable in one compilation unit, g++ isn't detecting
this as non-standard C++.

There is a proposal on the table that makes it unnecessary to define
a static integral constant *unless* its address is taken. Your program
should be valid in either case.
Hooray!
I can't find any reference to this in TC++PL, 3rd Ed, to clarify my
confusion. I've tried checking the index under "static member" and no
mention is made of the need to define static members in exactly one
compilation unit.

What's going on? Do I have to define it or not?

You do, as of now, to be fully standard-compliant. However, you do
not, with many implementations today, who are (in this regard) running
ahead of the standardisation process.
Well, I've patched up the code by placing #ifndef _MSC_VER / #endif around
the jimmy.cpp definition line; though I wonder if it's really worth the
effort.

Philip
Jul 26 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

8
3528
by: VJ | last post by:
Hi, I apologize if this question has been asked many times on the group! I am new to programming, I know that there are three section in address space- one for code, one for stack, and the third for Heap. I just want to know how and where static members are stored in the address space given to particular program. Is this different from...
2
3576
by: Drew McCormack | last post by:
I am getting an error in g++ 4.0.0 that I did not get in g++ 3.4. I have a header with the following const variables with namespace scope: namespace Periphery { extern const double ProtonMassInAtomicUnits = 1836.152755656068; } I try to use these in another header to initialize static const member
9
6349
by: Bryan Parkoff | last post by:
I have noticed that C programmers put static keyword beside global variable and global functions in C source codes. I believe that it is not necessary and it is not the practice in C++. Static keyword is useful inside struct, class, and function only unless you want to force local variable to be global variable so static is used. Do you...
1
2119
by: John Ratliff | last post by:
Do I have to declare store in my implementation file for all static member variables, even when they are const ints? In Windows, using msys with g++ 3.4.2 and whatever linker I'm not sure (probably gnu binutils), I didn't have to declare storage for any of my static const integer member variables, but in Linux, the linker can't find four of...
3
5696
by: Diebels | last post by:
Hi, I have some problems using static variables which results in a core dump. I have attached code and coredump to the end of my message. I am trying to implement a kind of factory design. I have a base class with several sub classes. In runtime I want to create a instance of a sub class and assign it to a base class pointer. Nothing...
5
3592
by: mast2as | last post by:
Hi guys Here's the class I try to compile (see below). By itself when I have a test.cc file for example that creates an object which is an instance of the class SpectralProfile, it compiles fine. 1 / Now If I move the getSpectrumAtDistance( const T &dist ) method definition in SpectralProfofile.cc let's say the compiler says ...
3
5834
by: Steve Folly | last post by:
Hi, I had a problem in my code recently which turned out to be the 'the "static initialization order fiasco"' problem (<http://www.parashift.com/c++-faq-lite/ctors.html#faq-10.12>) The FAQ section describes a solution using methods returning references to static objects. But consider:
9
8868
by: Jess | last post by:
Hello, I was told that if I declare a static class constant like this: class A{ static const int x = 10; }; then the above statement is a declaration rather than a definition. As I've *defined* "x"'s value to be 10, isn't above statement a
14
5988
by: Jess | last post by:
Hello, I learned that there are five kinds of static objects, namely 1. global objects 2. object defined in namespace scope 3. object declared static instead classes 4. objects declared static inside functions (i.e. local static objects) 5. objects declared at file scope.
4
5805
by: aaragon | last post by:
Hi everyone, I have a linking error when using gcc4.2 and static member variables. The class template definition is something around the following: template<> class Element<L2_t: public Element_common<L2, Side<2,2 { public:
0
7471
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language...
0
7740
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. ...
0
7985
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that...
1
7503
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For...
0
7830
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the...
0
6071
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then...
1
5387
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes...
0
3517
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in...
0
3496
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.