7

I have read that the difference between globals and static globals is that the global variable can be referred to in another implementation file via extern, whereas static globals are localized to only that implementation file. See these two questions for more information: [1, 2].

From what I understand, this means the that the following foo() and bar() should be linked identically. Both functions can only be used by MyClass.

//MyClass.h
Class MyClass{
private:
  static void foo();
};

//MyClass.cpp
void MyClass::foo(){}
static void bar(){}

I can see foo()'s declaration being more common since it lets the header file lay out the entire class more completely (even if you can't/shouldn't use the private stuff), but is bad practice declare a function like bar() (hidden from the header file)?

For context, I am defining a WNDPROC for windows messages which needs to be static to work, but it's a rather ugly declaration and I'm not sure if I should hide it completely in the implementation file or go ahead and declare it in the header file.

Community
  • 1
  • 1
Suedocode
  • 2,504
  • 3
  • 23
  • 41
  • 1
    It is not a bad practice, it is a *good* practice. The less symbols the linker has to handle, the faster it will run and the less likely the accidents. A window procedure certainly ought not be visible outside the source code file, it is pure implementation detail of the window. – Hans Passant Jul 29 '13 at 16:09
  • @HansPassant so why is it ever necessary to declare any private static member functions? Wouldn't they all be pure implementation details in every case? And what about other private static member variables (as opposed to functions) that are also used as a pure implementation detail? – Suedocode Jul 29 '13 at 16:16
  • I see where you are going. It is a bit annoying to put in a header file something you may use only in one source file. However the meaning is not identical as I have explained in my other comment. – Neil Kirk Jul 29 '13 at 16:20
  • It isn't necessary, it is just easier. You avoid it by using interfaces. – Hans Passant Jul 29 '13 at 16:23

1 Answers1

13

static is a very horrible keyword as it has many different meanings depending on the context. static variables and static functions are completely different, and a static function in a class and a static free-function are completely different.

A static function in a class means that the function can be called without an instance of the class, but it cannot access non-static members of the class. It is a bit like a regular function, just enclosed in the class for tidiness purposes.

A static free-function has internal linkage, so it cannot be seen outside of the source file and its name can be reused in other source files.

A static class function does not have internal linkage. All class functions have external linkage. You can split the class function between header and source files whether the class function is static or not.

I recommend you read some tutorials/books to understand the many different uses of static more clearly. When you see static in a place you've not seen it before, assume nothing!

If you have a free-function which you want hide in a source file, you can declare it static as you have done so. Alternatively you can place it in an unnamed namespace.

// cpp file only
namespace
{
    void hiddenfunc() {..}
}

This is similar to

static void hiddenfunc();

And it can be called in the same way (just as "hiddenfunc()"). An advantage of unnamed namespaces (a weird name, I know) is that you can also place classes and other definitions, that you only want to be visible within that source file. Just make sure you define the function body within the namespace {..} area. Don't put an unnamed namespace in a header file.

Neil Kirk
  • 21,327
  • 9
  • 53
  • 91
  • Another example of the difference. A static variable in a class is global across the whole project with only one instance. This is opposite to other kinds of "static varible" which may be unique to each source file. Very sticky keyword indeed. – Neil Kirk Jul 29 '13 at 16:14
  • Hmmm okay I was mistaken when I said "they are linked identically", but as long as the static member function is private then their uses should be identical right? – Suedocode Jul 29 '13 at 16:16
  • Perhaps in your situation but not in general. The private function can only be used by that class. But the class functions could, in theory, be split across multiple source files, and any could call the private function. You could also declare a friend class or function, which can call the private function from elsewhere. On the other hand, your static free-function can only be called in that one source file, plus it can be called by anything in that source file, not just your one class. Other classes or functions you may have in the source file for some reason, can also call it. – Neil Kirk Jul 29 '13 at 16:19
  • Ahhh I had not thought of multiple source files that define class functions together! Good point. – Suedocode Jul 29 '13 at 16:22