0

I'm interested in what exactly happens "under the hood" when the following inline function is called in several translation units.

namespace some_name
{
    inline const float& get_float()
    {
        static const float a = 5.0f;
        return a;
    }
}

My intention was to create an externally linked variable 'a', which can be used across the code (if the header with namespace is included), but also I wanted to prevent any change to this variable. From testing it seems I succeeded, but I'm interested in what exactly happens when I call this function the first time and then the next several times.

Additional question: Am I polluting global namespace with static variable declaration/definition?

  • 1
    As an alternative to making a function to return a static const float, why not just make it a member variable of a class, or even of the namespace; it's still const... – UKMonkey Apr 07 '17 at 07:54
  • UKMonkey I was not sure, if I do it like that, then every time I use the variable in different translation unit I would get a copy of type const float. – FrantišekV Apr 07 '17 at 08:00
  • 1
    Are you sure that this way `a` is externally linked? And why do you even need an externally linked constant? External linkage suggests that multiple compilation units share one instance of a variable and when it changes, every unit would read the updated value. But the constant is not expected to change. Moreover, in many cases the compiler is going to embed the constant value directly into the instruction, so that it won't even appear in memory. – Eduard Malakhov Apr 07 '17 at 08:14
  • If you're interested in finding out, there's no mystery here. Most compilers can give you an assembly-level view of exactly what code they generated for this. – tadman Apr 07 '17 at 08:23

1 Answers1

1

but I'm interested in what exactly happens when I call this function the first time and then the next several times.

The initialization is static (doesn't depend on anything at run-time), so it is probably performed at the start of the program. All calls simply return a reference to the static object. And those calls are probably expanded inline, and so just use the static object directly.

A simpler option would be to use a global variable in the namespace.

Additional question: Am I polluting global namespace with static variable declaration/definition?

No. The static variable is local, so doesn't pollute any namespace. The function itself does "pollute" the namespace where it is declared.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • A `static` variable in the namespace would do the opposite, i.e. define one such variable per TU that includes the header. – Quentin Apr 07 '17 at 08:24
  • @Quentin yeah, I meant a global variable (i.e. a non-local variable with static storage). That doesn't really matter for constants though, since the duplicates from different compilation units are squashed anyway, aren't they? – eerorika Apr 07 '17 at 08:27
  • @Quentin This is exactly what I'm curious about. That is why I didn't define the variable in namespace. I want to use the specific one static object directly in all the TU which includes this header. – FrantišekV Apr 07 '17 at 09:33
  • @user2079303 not necassarily. This is about ODR-use and the rules are quite hairy, but in a nutshell, the difference is visible when you take the address of the constant. With a single definition (such as the local `static` or the `extern` global), the address is the same for all TUs, with `static` globals, it's not. – Quentin Apr 07 '17 at 09:38
  • @user3271640 then use `extern`. – eerorika Apr 07 '17 at 09:39
  • I actually tested it, and if I defined a static variable in namespace only, and then I call the variable from another TU, I get only it's (const float) copy with another address. That is not what I wanted. – FrantišekV Apr 07 '17 at 09:41
  • @user3271640 that is why you use `extern`, not `static`. – eerorika Apr 07 '17 at 09:42
  • @user2079303 Yes the extern should do it, but also, wouldn't it "pollute" the global namespace when I call the variable? – FrantišekV Apr 07 '17 at 09:44
  • @user3271640 you don't pollute the global namespace if you put the variable in the some_name namespace any more than you pollute the namespace with the function. – eerorika Apr 07 '17 at 09:57
  • Thank you for your answers, everything is more clear for me now. – FrantišekV Apr 07 '17 at 10:11