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?

Community
  • 1
  • 1
pgplus1628
  • 1,294
  • 1
  • 16
  • 22
  • 1
    In both functions, static variable is only initialized once. – Jarod42 Jun 21 '16 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. – pgplus1628 Jun 21 '16 at 15:29
  • 1
    Look at [whats-the-difference-between-assignment-operator-and-copy-constructor](http://stackoverflow.com/questions/11706040/whats-the-difference-between-assignment-operator-and-copy-constructor) – Jarod42 Jun 21 '16 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. – pgplus1628 Jun 22 '16 at 02:22

1 Answers1

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...

lorro
  • 10,687
  • 23
  • 36
  • 1
    "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. – Dark Falcon Jun 21 '16 at 14:24
  • @DarkFalcon thanks. – pgplus1628 Jun 21 '16 at 14:48
  • @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. – Jarod42 Jun 21 '16 at 15:23
  • @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 Jun 21 '16 at 15:29
  • 1
    @lorro, fair enough. Might want to clarify that. The correct terminology is (I think) "function static variable with automatic storage duration" – Dark Falcon Jun 21 '16 at 15:34