Static keyword does not have the same meaning in C or C++ :

C's static ~= C++'s private

static keeps its meaning for functions in a specific compilation unit: the symbol is not exported and (in gcc 3.4), interesting compilation schemes can be applied (basically, the compiler can break the C calling convention since nobody outside the compilation unit would be able to call the function).

Note that the anonymous namespace is the C++ way to achieve this.

For classes, static declares class-wide methods and data (same as in Java).

That is, the static methods and data are not attached to a specific object, but to the class itself.

It is different from namespaces since the access keywords (”“public””, ”“protected””, ”“private””) apply

(a namespace is basically a class were all methods are static and everything is public.

of course, by using namespaces you get to use the ”“using”” and ”“using namespace”” keywords)

C++ static Class members (explained by <Doudou>)

static variables declared inside classes are only declarations.

when you write :

class Foo { static myObject whatever; }

you HAVE to do a :

myObject Foo::whatever;

elsewhere (.cpp) in order to allocate the object

That is, you need to put the variable in a compilation unit in order to get it allocated.

Why ? Because you often have to define the class in a header.

If the static keyword would allocate the | the symbol would be allocated once in each compilation unit that includes the header.

Note that you have the same problem with functions and methods, but that the inline keyword forces the compiler to merge the symbols.

static const

The exception is ”“static const””, at least for PODs. That is, you can do

class CPlusPlus { public: static const int m = 0; };
compiles on g++ not [[MSVC]]
# Microsoft (R) 32-bit C/C++ Standard Compiler Version 12.00.8168 for 80x86
# cplusplus.cpp(1) : error C2252: 'm' :
# pure specifier can only be specified for functions

But only on integral types (int, char ..)

class CPlusPlus { public: static const float m = 0; };
#  g++ -pedantic -c cplusplus.cpp cplusplus.cpp:1: error: ISO C++ forbids
# initialization of member constant `m' of non-integral type `const float'



1st I suspected that the problem was related to C++ templates default allocators…. but Zif & Doudou helped and confirm that static members must be allocated in objects (.cpp)

But how comes that on final link Allocation is “mandatory” for some cases and not for others. Lets conclude that “it's mandatory when it is requiered” :-/ ?

# pr -t -o 1 -w 80 cppstatic.cpp
/// @author:
/// PROJECT=cppstatic ;  make ${PROJECT} && ./${PROJECT} ; rm ./${PROJECT}
/// PROJECT=cppstatic ;  make ${PROJECT} CXXFLAGS="-DMEMBER" && ./${PROJECT} ; rm ./${PROJECT}
#include <iostream>
using namespace std;
#define debug(x) cerr<<"# " <<(x)<<endl;
template<class T>
class TCls {
 T m;
// #pragma instantiate TCls<int> // doenst not help either
class Cls {
 static int main(int argc=0, char** arg = 0);
 static Cls instance; // default allocator is (not really) called
#ifdef MEMBER
 static TCls<int> mt; // default allocator is NOT called , why ? HELP
TCls<int> Cls::mt; //  default allocator is called
int Cls::main(int argc, char** argv ) {
#ifndef MEMBER
 TCls<int> Cls::mt; //  default allocator is called
 mt.m = 1;
int main(int argc, char* argv[[]] ) {
 Cls::instance.main(argc, argv); //ok
 Cls::main( argc, argv ); // ok
 debug(__PRETTY_FUNCTION__); //just print "main"
g++ --version | head -1
g++ (GCC) 3.3.1 (Mandrake Linux 9.2 3.3.1-2mdk)
PROJECT=cppstatic ;  make ${PROJECT} && ./${PROJECT} ; rm ./${PROJECT}
g++     cppstatic.cpp   -o cppstatic
# int main(int, char**)
PROJECT=cppstatic ;  make ${PROJECT} CXXFLAGS="-DMEMBER" && ./${PROJECT} ; rm ./${PROJECT}
g++ -DMEMBER    cppstatic.cpp   -o cppstatic
ccKZVVHu.o(.text+0xd): In function `Cls::main(int, char**)':
: undefined reference to `Cls::mt'
collect2: ld returned 1 exit status
g++ -DMEMBER -DSTATIC_MEMBER    cppstatic.cpp   -o cppstatic
# int main(int, char**)
  • /
//#ident "$Id:*"

Answsers :

<zif> explanation :

Don't forget that C++ is not Java and that macros are Evil. </zif>

<zif>And you, try to get better examples. C++ is a lazy language with lazy compilers.

If I add a public method 'void foo(){}' to Cls, If i call in main: ';' I will get:

/tmp/ccRMvkjc.o(.text+0x39): In function `main':
: undefined reference to `Cls::instance'
collect2: ld returned 1 exit status

Adding a 'Cls Cls::instance;' in the static part of the unit will correct this. What's your point, again ?

(BTW, editing other people's text on a wiki is quite rude)</zif>

<Doudou> well, it has to do with a #ifndef MEMBER which should be a #ifndef STATIC_MEMBER :) in the case were you only define MEMBER you only declare mt, you never allocate it.

C++ templates declaration is done when the compiler decides to do it .

Just read the gcc infopage for more informations on C++ template instanciation



  • <Doudou> : you're The Expert to hire === got url ?===
  • <zif> : your brain is more precious than a MSDN url :)


@TaG: C++ Programming C virtual OOP GCC MSVC virtualstatic

<iframe width="560" height="315" src="" frameborder="0" allowfullscreen></iframe>

www.stationartselectroniques.com_emotion2004_images_emotion2004_artistes_transpermia_trans_photo_01dedal_m_antunez.jpg tunez.jpg}}

static.txt · Last modified: 2020/09/08 20:49 (external edit)
Except where otherwise noted, content on this wiki is licensed under the following license: CC Attribution-Share Alike 3.0 Unported
Recent changes RSS feed Donate Powered by PHP Valid XHTML 1.0 Valid CSS Driven by DokuWiki