About static member variable

Y

yanlinlin82

I'd like to write all code of a class in only header file. But when
there is any static member varia ble, I have to define it in cpp file,
not the header file. Otherwise, the static member variable may be
duplicated because two or more cpp files may include the header.
How can I solve this without the cpp file, which used to define the
static member variable?
Thanks!
 
V

Victor Bazarov

I'd like to write all code of a class in only header file. But when
there is any static member varia ble, I have to define it in cpp file,
not the header file. Otherwise, the static member variable may be
duplicated because two or more cpp files may include the header.
How can I solve this without the cpp file, which used to define the
static member variable?

Simple. Don't use any static variables.

If you can asnwer the following questions, you can answer your own:

"I like walking outside when it's raining, and stay dry, but I
don't want to wear any rain gear or carry an umbrella. How to
accomplish my goal?"

"I want to live a long life and be healthy, but I don't want to
give up smoking or alcohol or drugs. How can I do that?"

V
 
A

Alf P. Steinbach

* (e-mail address removed):
I'd like to write all code of a class in only header file. But when
there is any static member varia ble, I have to define it in cpp file,
not the header file. Otherwise, the static member variable may be
duplicated because two or more cpp files may include the header.
How can I solve this without the cpp file, which used to define the
static member variable?

The best way is to avoid static variables, except constants: using them
is an all too common beginner's mistake, much like using goto.

Constants are not problematic, just use 'const':

const int x = 42;

Here you don't need to be concerned about duplication because a
namespace scope constant has internal linkage by default.

That said, technical solutions to non-const static variable in headers
include using local statics (wrapping in functions) and templatizing.

But best, just say no: you can be nearly 100% sure that it's a mistake.


Cheers, & hth.,

- Alf
 
A

Alf P. Steinbach

* Victor Bazarov:
"I want to live a long life and be healthy, but I don't want to
give up smoking or alcohol or drugs. How can I do that?"

It seems that yogurt is key.

At least in Kazakhstan and places like that.

Cheers, & hth.,

- Alf
 
Y

yanlinlin82

Thanks for all your funny answers! :D

It sounds that I have asked for way to an unreachable thing. But I
have found such requirements in real life indeed, while I also have
some "wacky" habit (such as writing class implement in header file
only).

There is a example in Microsoft's ATL. I found class CWindow has a
static member rcDefault. Microsoft use its own keyword
"_declspec(selectany)" to slove this problem. I am curious if there is
a common solution via C++ language itself.
 
J

James Kanze

I'd like to write all code of a class in only header file.

Why? The header file is visible by all users; the more you put
in it, the more coupling you get, and the harder it is to
maintain the program.
 
K

Kai-Uwe Bux

James said:
Why? The header file is visible by all users; the more you put
in it, the more coupling you get, and the harder it is to
maintain the program.

There may be thousands of good reasons to separate header files from
implementation files, but that one, I do not consider convincing.

A header is meant for the compiler only. Users refer to the documentation.
They have no business looking at the header. There is no coupling coming
from this (unless users prefer to rely on undocumented features, which is
entirely their problem).

Likewise: you don't get coupling from the standard headers should they be
readable on a particular implementation. Why would you from another header?


Best

Kai-Uwe Bux
 
I

Ian Collins

Kai-Uwe Bux said:
There may be thousands of good reasons to separate header files from
implementation files, but that one, I do not consider convincing.
This time, I agree with James.
A header is meant for the compiler only. Users refer to the documentation.
They have no business looking at the header. There is no coupling coming
from this (unless users prefer to rely on undocumented features, which is
entirely their problem).
Maybe, but headers have a strange way of finding themselves included in
compilation units, the "lower level" the header, the more places both
directly and indirectly it gets included. If there is code in the
header and the project is under development, that code is likely to get
changed, which results in all those compilation units being recompiled.
Likewise: you don't get coupling from the standard headers should they be
readable on a particular implementation. Why would you from another header?
You don't change your standard headers.
 
K

Kai-Uwe Bux

Ian said:
This time, I agree with James.

With the recommendation, or with the reasoning? I did not dispute the
former.
Maybe, but headers have a strange way of finding themselves included in
compilation units, the "lower level" the header, the more places both
directly and indirectly it gets included. If there is code in the
header and the project is under development, that code is likely to get
changed, which results in all those compilation units being recompiled.

That is a one of the thousand other reasons I acknowledged. But maybe, I
just misunderstood what James had in mind when he was saying "visible by
all users". I took that to refer to human users not files that include the
header.
You don't change your standard headers.

True. But they are visible by all users :)

I thought, it was clear from my topic sentence that I have no problem with
the recommendation per se to put the implementation into a different file.
I just question the particular rationale.


Best

Kai-Uwe Bux
 
Y

yanlinlin82

James Kanze said:
Why? The header file is visible by all users; the more you put
in it, the more coupling you get, and the harder it is to
maintain the program.
I don't think that putting all code in header file would increase the
coupling. Since the implementation code is private in class, users can
ignore them usually.

The reason I do this is from the occasion that I publish my code to
others in Windows platform. There are many compiling types for library
(such as multi-threading, multi-threading DLL), and every type can
build as both Debug and Release (as well as ANSI or Unicode, etc.). As
a result, I have to give so many different .lib files. If I publish
my .h and .cpp files, troubles also can be met. Target projects always
need to be changed, to add my .cpp file as one compiling unit. So, I
publish only header files finally, they can only use #include to use
my code now.
 
J

James Kanze

There may be thousands of good reasons to separate header files from
implementation files, but that one, I do not consider convincing.
A header is meant for the compiler only. Users refer to the documentation.
They have no business looking at the header.

Totally agreed.
There is no coupling coming from this (unless users prefer to
rely on undocumented features, which is entirely their
problem).

The coupling has nothing to do with what the user reads. It's
related to what the compiler must read. Anytime anything in the
header file changes, all of the client code must be recompiled.
Likewise: you don't get coupling from the standard headers
should they be readable on a particular implementation. Why
would you from another header?

Well, you do get coupling; that's why e.g. iosfwd was
introduced. But it's not normally as serious a problem; the
implementation of the standard library only changes when you
change the compiler, which you don't do very often, and you have
to do a complete rebuild anyway when you do that anyway.
 
J

James Kanze

With the recommendation, or with the reasoning? I did not dispute the
former.
That is a one of the thousand other reasons I acknowledged.
But maybe, I just misunderstood what James had in mind when he
was saying "visible by all users". I took that to refer to
human users not files that include the header.

I should have been clearer. I was talking about compile time
coupling. Quite frankly, it didn't even occur to me that human
beings would read a header file (other than to modify it).

In practice, it sometimes does go beyond just the compiler,
however. I've worked on projects where the header files were
all automatically generated (by Rational Rose), and the
"average" developer couldn't even check them out from the source
code repository; he only had read access to them. But that's
still another issue.

[...]
I thought, it was clear from my topic sentence that I have no
problem with the recommendation per se to put the
implementation into a different file. I just question the
particular rationale.

Perhaps I didn't express the rationale clearly. I was definitly
thinking of the fact that when you compile code, you read the
header file. (Or at least the compiler does.) And the fact
that most build systems have a granularity of the file; any
modification to the file triggers the recompilation of all the
source files which include it, directly or indirectly. Adding
implementation to the header means that client code (the object
files, if you prefer) are coupled to the implementation, and not
just the "contract".

(Note that sometimes, you exploit this coupling intentionally.
If change the contract of a function in such a way that it might
invalidate existing code, e.g. by making the pre-conditions
stronger, you also change something in the signature, so that
will not only be recompiled, but that it will fail to recompile
until it has been reworked to accept the new contract.)
 
J

James Kanze

I don't think that putting all code in header file would increase the
coupling. Since the implementation code is private in class, users can
ignore them usually.

Never the less, the granularity of the build system is usually
the file; modify the header, and you trigger the recompilation
of the client code; modify a separate source, and you don't. Or
wourse, if for some reason you don't recompile part of the code,
you get inconsistancies.
The reason I do this is from the occasion that I publish my code to
others in Windows platform. There are many compiling types for library
(such as multi-threading, multi-threading DLL), and every type can
build as both Debug and Release (as well as ANSI or Unicode, etc.). As
a result, I have to give so many different .lib files. If I publish
my .h and .cpp files, troubles also can be met. Target projects always
need to be changed, to add my .cpp file as one compiling unit. So, I
publish only header files finally, they can only use #include to use
my code now.

If you want to offer all of the options, you almost have to
provide source, and let the user build the library. Most
libraries I know don't, however. They provide a single .so or
..a, depending on whether they are designed to be linked
dynamically or statically, and the necessary headers.
Typically, you won't have debugging information in the library,
but this is not a problem, because you won't have to debug it.
(What you deliver to the customer is always a "release" build.
By definition.)
 
J

Juha Nieminen

Alf said:
Constants are not problematic, just use 'const':

const int x = 42;

He was talking about *member* variable (well, a static "member"
variable would technically not be a member variable but a class
variable, but I assume that with "member variable" he meant "class
variable", ie. a static variable inside the scope of a class).

You can't write that for member variables (well, at least not until
the next C++ standard). You can, however, write this:

static const int x = 42;

I'm wondering though: What does the standard say about such static
const variables? Do they need an actual instance or not?

AFAIK not having an actual instance of such a variable can be
problematic if someone takes a pointer to it. A pointer requires that
the variable has an actual physical instance. Moreover, IIRC all
pointers which reference the same variable should be identical (ie. it's
not ok for the compiler to simply instantiate the variable in the
current compilation unit if the code creates a pointer to the variable,
because all such pointers in different compilation units must point to
the same memory location, if I'm not completely mistaken).
 
V

Victor Bazarov

Juha said:
He was talking about *member* variable (well, a static "member"
variable would technically not be a member variable but a class
variable, but I assume that with "member variable" he meant "class
variable", ie. a static variable inside the scope of a class).

You can't write that for member variables (well, at least not until
the next C++ standard). You can, however, write this:

static const int x = 42;

I'm wondering though: What does the standard say about such static
const variables? Do they need an actual instance or not?

AFAIK not having an actual instance of such a variable can be
problematic if someone takes a pointer to it.

I belive you mean "obtains its address". The actual wording I think
I've seen is "uses it in the context that treats it as an l-value",
which could mean taking its address, initialising a reference with
it, etc. (although I am not sure what's in 'etc')
A pointer requires that
the variable has an actual physical instance. Moreover, IIRC all
pointers which reference the same variable should be identical (ie.
it's not ok for the compiler to simply instantiate the variable in the
current compilation unit if the code creates a pointer to the
variable, because all such pointers in different compilation units
must point to the same memory location, if I'm not completely
mistaken).

I believe you're bringing up the ODR, which should hold for the program
to be a standard C++ program.

V
 
P

Pete Becker

He was talking about *member* variable (well, a static "member"
variable would technically not be a member variable but a class
variable, but I assume that with "member variable" he meant "class
variable", ie. a static variable inside the scope of a class).

The language definition uses the term "static members" to refer to,
well, static members. They are static and they are members. C++ does
not have the formal notion of "class variable", and using that term
leads to confusion.
 
J

Juha Nieminen

Pete said:
The language definition uses the term "static members" to refer to,
well, static members. They are static and they are members. C++ does not
have the formal notion of "class variable", and using that term leads to
confusion.

Well, I believe that the distinction between "member functions" and
"class functions" is quite common. Why shouldn't the same distinction be
made with variables?
 
V

Victor Bazarov

Juha said:
Well, I believe that the distinction between "member functions" and
"class functions" is quite common. Why shouldn't the same distinction
be made with variables?

I've not seen "class functions" up until your post. What does it mean?

V
 
A

Alf P. Steinbach

* Juha Nieminen:
He was talking about *member* variable (well, a static "member"
variable would technically not be a member variable but a class
variable, but I assume that with "member variable" he meant "class
variable", ie. a static variable inside the scope of a class).

You can't write that for member variables (well, at least not until
the next C++ standard). You can, however, write this:

static const int x = 42;

For integral type, yes.

Sorry, I didn't see that about member variables.

However, the two solutions I mentioned, "technical solutions to
non-const static variable in headers include using local statics
(wrapping in functions) and templatizing", work also for member constant
variables, including non-integral ones.

struct Foo
{
static double x() { return 3.15; }
};

// Foo::x()


template< typename Dummy > struct XValue{ static double const x; }
template< typename Dummy > double const XValue<Dummy>::x = 3.15;

struct Bar: XValue<void> {};

// Bar::x


I'm wondering though: What does the standard say about such static
const variables? Do they need an actual instance or not?

If such a variable is used in a way that requires it has an address. With

static const int x = 42;

as a member variable it becomes a declaration instead of definition
(very confusing), and then a definition outside the class definition is
required, which looks like a declaration:

int const SomeClass::x;

and which is problematic in a header file.

And which is also generally problematic. Different compilers differ in
how strictly they interpret the standard in this respect. A compiler
(or in practical terms linker) may choke on code that follows the standard.

So, best avoided.


Cheers, & hth.,

- Alf
 
P

Pete Becker

Well, I believe that the distinction between "member functions" and
"class functions" is quite common. Why shouldn't the same distinction be
made with variables?

It's not about making the distinction, but about what you call it. The
language definition uses the term "static member" to refer to static
members, both functions (as in "static member function") and data (as
in "static member data"). Don't invent new terms.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,770
Messages
2,569,583
Members
45,075
Latest member
MakersCBDBloodSupport

Latest Threads

Top