Search code examples
c++storage-class-specifier

What storage class is a static inside a function and why?


If I'm using a singleton pattern (yeah, I know - they're usually bad)... and I had an instance function like so:

MySingleton* Instance() {
    static MySingleton instance;
    return &instance;
}

what storage class is instance?

I'm reading "Programming With POSIX Threads by David R. Butenhof", and I came across text that said:

Most of the time you'll probably declare condition variables using the extern or static storage class at file scope, that is, outside of any function. They should have normal (extern) storage class if they are used by other files, or static storage class if they are used only within the file that declares the variable.

Since this static is inside a function, is it auto? or is the class different because of the static key word?

If I moved the 'instance' variable to be static and global (not in any function) in its file - could I still give a reference to it to another file, or would that not work?


Solution

  • I think the author has conflated storage duration and linkage, although the advice what keywords to use is correct.

    Your function-scope variable instance has static storage duration. Without the static keyword it would have automatic storage duration.

    An object at file scope always has static storage duration (well, or thread storage duration in C++11 with keyword thread_local). Using the static keyword at file scope gives the object internal linkage, extern gives it external linkage, they don't affect storage duration.

    Describing something has having "static storage class" is correct, since static is a so-called "storage class specifier", but it's not the whole story since the meaning of static in file scope is different from the meaning in function scope.

    You can pass around a reference to an object with static storage duration to code from other translation units. It doesn't matter whether it has file scope or function scope, and it doesn't matter what its linkage is. "They should have normal (extern) storage class if they are used by other files" just means that a global needs external linkage if other files are going to refer to it by name, since a global name with internal linkage refers to a different object in each TU. Technically it's the name that has linkage, not the object.