I think the limitation you have considered is not related to semantics (why should something change if the initialization were defined in the same file?) but rather to the C++ compilation model which, for reasons of backward compatibility, cannot be easily changed because it would either become too complex (supporting a new compilation model and the existing one at the same time) or would not allow to compile existing code (by introducing a new compilation model and dropping the existing one). The C++ compilation model stems from that of C, in which you import declarations into a source file by including (header) files. In this way, the compiler sees exactly one big source file, containing all the included files, and all the files included from those files, recursively. This has IMO one big advantage, namely that it makes the compiler easier to implement. Of course, you can write anything in the included files, i.e. both declarations and definitions. It is only a good practice to put declarations in header files and definitions in .c or .cpp files. On the other hand, it is possible to have a compilation model in which the compiler knows very well if it is **importing the declaration** of a global symbol that is **defined in another module**, or if it is **compiling the definition** of a global symbol **provided by the current module**. Only in the latter case the compiler must put this symbol (e.g. a variable) in the current object file. For example, in [GNU Pascal][1] you can write a unit ``a`` in a file ``a.pas`` like this: unit a; interface var MyStaticVariable: Integer; implementation begin MyStaticVariable := 0 end. where the global variable is declared and initialized in the same source file. Then you can have different units that import a and use the global variable ``MyStaticVariable``, e.g. a unit b (``b.pas``): unit b; interface uses a; procedure PrintB; implementation procedure PrintB; begin Inc(MyStaticVariable); WriteLn(MyStaticVariable) end; end. and a unit c (``c.pas``): unit c; interface uses a; procedure PrintC; implementation procedure PrintC; begin Inc(MyStaticVariable); WriteLn(MyStaticVariable) end; end. Finally you can use units b and c in a main program ``m.pas``: program M; uses b, c; begin PrintB; PrintC; PrintB end. You can compile these files separately: $ gpc -c a.pas $ gpc -c b.pas $ gpc -c c.pas $ gpc -c m.pas and then produce an executable with: $ gpc -o m m.o a.o b.o c.o and run it: $ ./m 1 2 3 The trick here is that when the compiler sees a **uses** directive in a program module (e.g. uses a in b.pas), it does not include the corresponding .pas file, but looks for a .gpi file, i.e. for a pre-compiled interface file (see [the documentation][2]). These ``.gpi`` files are generated by the compiler together with the ``.o`` files when each module is compiled. So the global symbol ``MyStaticVariable`` is only defined once in the object file ``a.o``. So IMO the reason why in C++ you have to define static data members in a separate file is more related to the C++ compilation model than to limitations imposed by the linker or other tools used by the compiler. In C++, importing some symbols means to build their declaration as part of the current compilation unit. This is very important, among other things, because of the way in which templates are compiled. But this implies that you cannot / should not define any global symbols (functions, variables, methods, static data members) in an included file, otherwise these symbols could be multiply-defined in the compiled object files. [1]: http://www.gnu-pascal.de/gpc/h-index.html [2]: http://www.gnu-pascal.de/gpc/GPI-files.html