0

recently I saw a piece of code as follows :

namespace {
    mutex* get_server_factory_lock() {
        static mutex server_factory_lock;
        return &server_factory_lock;
    }

    typedef std::unordered_map<string, ServerFactory*> ServerFactories;
    ServerFactories* server_factories() {
        static ServerFactories* factories = new ServerFactories; 
        // is variable factories assigned every time this function called ? 
        return factories;
    }
}  // namespace

/* static */
void ServerFactory::Register(const string& server_type,
                         ServerFactory* factory) {
    mutex_lock l(*get_server_factory_lock());
    if (!server_factories()->insert({server_type, factory}).second) {
        LOG(ERROR) << "Two server factories are being registered under "
            << server_type;
    }
}

It seems that function server_factories() is similar to the singleton.
My question is : to the best of my knowledge, factories is a static variable, and every time function server_factories() called, this static variable will be assigned a new value. But the result is not, every time server_factories() is called, it returns the same pointer. Why?

PS : with c++11 enabled when compiling.

Duplicated with What is the lifetime of a static variable in a C++ function?

4
  • 1
    In both functions, static variable is only initialized once. Commented Jun 21, 2016 at 14:21
  • @Jarod42 Ok, thanks. But I still wonder why static ServerFactories* factories = new ServerFactories; is considered as initialization, not an assignment when server_factories() called in the second time. Commented Jun 21, 2016 at 15:29
  • 1
    Look at whats-the-difference-between-assignment-operator-and-copy-constructor Commented Jun 21, 2016 at 15:43
  • @Jarod42 that link didn't help. I think it's an assignment operation, not copy operation. If so, the factories variable should be changed every time server_factories() is called. Commented Jun 22, 2016 at 2:22

1 Answer 1

2

It's a static, so it only gets initialized once, when you first enter the function. Later calls to the same function use the previous variable. That said, I fail to see why it's a pointer and not a simple function static variable (with automatic storage duration) that we could take the address of...

Sign up to request clarification or add additional context in comments.

5 Comments

"That said, I fail to see why it's a pointer and not a simple static that we could take the address of" << Because perhaps ServerFactories() uses other global variables. If it were also a global, initialization order across translation units would be undefined. By making it a function-local static, initialization order becomes well-defined. Whether this is needed in his case is unknown, but this is a frequent reason for this pattern.
@DarkFalcon thanks.
@DarkFalcon: in get_server_factory_lock(), there is no new, and you can still have well defined behavior. There is no points to do allocation.
@DarkFalcon: by simple static I mean static within the function, but not pointer (sorry if my wording was confusing), like this: ServerFactories* server_factories() { static ServerFactories factories; return &factories; } Editing the answer accordingly.
@lorro, fair enough. Might want to clarify that. The correct terminology is (I think) "function static variable with automatic storage duration"

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.