473,320 Members | 1,838 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,320 software developers and data experts.

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::foo==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@@2HB) 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 2860
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::foo==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@@2HB) 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.********@comAcast.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.********@comAcast.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.********@comAcast.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@@2HB) 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.********@comAcast.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

"Andrey Tarasevich" <an**************@hotmail.comwrote in message
news:12*************@news.supernews.com...
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
Thanks for the clarification, Andrey.

-Howard

Jul 26 '06 #11

"Victor Bazarov" <v.********@comAcast.netwrote in message
news:ea**********@news.datemas.de...
Howard wrote:
>"Victor Bazarov" <v.********@comAcast.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.
Ok, good to know.
>
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.
Andrey provided a good explanation. I've tried looking at the Standard, but
it makes my head spin. I'm good at coding, but I just can't seem to
understand that kind of "legalese". Thanks anyway...

-Howard

Jul 26 '06 #12
Philip Potter wrote:
[..] What is the ODR?
One Definition Rule.
[..]
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 #13

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

Similar topics

8
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...
2
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...
9
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...
1
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...
3
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...
5
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...
3
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...
9
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...
14
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...
4
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...
0
by: DolphinDB | last post by:
Tired of spending countless mintues downsampling your data? Look no further! In this article, you’ll learn how to efficiently downsample 6.48 billion high-frequency records to 61 million...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
1
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
0
by: Defcon1945 | last post by:
I'm trying to learn Python using Pycharm but import shutil doesn't work
0
by: Shællîpôpï 09 | last post by:
If u are using a keypad phone, how do u turn on JavaScript, to access features like WhatsApp, Facebook, Instagram....
0
by: af34tf | last post by:
Hi Guys, I have a domain whose name is BytesLimited.com, and I want to sell it. Does anyone know about platforms that allow me to list my domain in auction for free. Thank you
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...

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.