static class variable without definition question
-
I do not follow why I do not get a compiler/linker error message for the following:
// `.h` file class Foo { static int bar; } // .cpp file Foo something;
This compiles and links fine (gcc 9.4.). I expected it to complain "no definition for
Foo::bar
", or similar.If in the
.cpp
I go e.g.abc = Foo::bar
then I do get the error (likeUndefined reference to Foo::bar
). And then I need to putFoo::bar = 0;
into.cpp
, as I would expect to have to do.My question is: why does C++ allow me to declare the
static bar
in the class declaration and then fail to provide a definition, so long as I do not try to reference it?For example, if I declared a member method,
int method();
, in the class.h
file, it would demand I provided the body for it, that would not be optional if I didn't call the method. -
Class statics are just glorified namespaces. Static member variables are just globals. They don't contribute to class size or layout. Static member functions are, similarly, just a regular global functions. They can't be virtualized and they are not part of vtable. It's like a forward declaration if you don't define it. No harm in it and linker is happy if nothing references it.
Worth mentioning is that this is the case for simple int. If the member was a class with custom constructor/destructor it couldn't be omitted, because creation and destruction of the static could have side effects. -
@mpergand said in static class variable without definition question:
Seems the linker doesn't complain until you use it somewhere.
Yeah. But true for, say, member methods, i.e. error if not defined without you needing to call. Doubtless because of
vtable
.I didn't try what happens with same cases if I tried a static method in class,
static int bar();
instead of variablebar
. I wonder whether that does not error if you never callFoo::bar()
? I suppose that will be the same and will be fine, sostatic
definitions (variables or methods) only matter if you actually use them. -
Class statics are just glorified namespaces. Static member variables are just globals. They don't contribute to class size or layout. Static member functions are, similarly, just a regular global functions. They can't be virtualized and they are not part of vtable. It's like a forward declaration if you don't define it. No harm in it and linker is happy if nothing references it.
Worth mentioning is that this is the case for simple int. If the member was a class with custom constructor/destructor it couldn't be omitted, because creation and destruction of the static could have side effects. -
@Chris-Kawa
Yes, thank you for clarifying, this is about the conclusion I had come to myself.I now get that
class Foo { static int bar; }
behaves for my question's purpose similarly toextern int bar;
as a global in C. This implies some module will provide aint bar;
implementation/storage definition. However, if nothing in any code actually references thatbar
then the linker won't care or complain; once something does then the linker will error with "can't find it". In this sense, C++ class-static variables (and for that matter functions/methods) behave the same. So it's just a glorifiedextern
, and I get it now :)