Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inline static const vs static const variable

Tags:

c++

I cant figure out what solution is better as I don't clearly understand the difference. I want to have a file that includes some variables that can be freely used throughout the program. My first attempt was the following:

Header file (Hosts.h)

#pragma once

#include <string>

namespace Some::Namespace {

using std::string;

class Hosts {
public:
    static const unsigned int SOME_DEVICE_PORT;
    static const string SOME_DEVICE_IP;
};
}

Implementation file (Hosts.cpp)

#include <Network/Hosts.h>

namespace Some::Namespace {
    const unsigned int Hosts::SOME_DEVICE_PORT = 10100;
    const string Hosts::SOME_DEVICE_IP = "192.168.1.1";
}

Then I became aware of the inline keyword which would make the implementation file redundant and you will be able to define the variables within the header file alone - just like this:

Header file with inline (Hosts.h)

#pragma once

#include <string>

namespace Some::Namespace {

using std::string;

class Hosts {
public:
    static const unsigned int SOME_DEVICE_PORT = 10100;
    inline static const string SOME_DEVICE_IP = "192.168.1.1";
};
}

Now my question is: How does these implementations differs in the matter of number of variable instances? Preferable I would like there to only be one instance of every variable. But will either of these solutions do this and are there other pitfalls regarding optimisation?

Thanks

like image 282
7heViking Avatar asked Jan 26 '23 18:01

7heViking


2 Answers

Expanding Mayur's answer, both methods are pretty similar. The main difference between both occurs when using inline static variables in libraries (.dlls and so forth).

With the inline variable, during the compile phase you will have an instance per each translation unit where it is used, and then the linker will remove all instances but one, referencing all translation units to the only instance not removed.

With the non-inline variable, there will be only one instance of the variable, then all the translation units will reference this variable.

In a single module (.exe, .dll...) this two use cases behave exactly the same.

But when linking together several .dlls with the .exe, with the inline variable, each module will have one instance, thus each module will reference its own instance. This may (or may not) be a problem. Since you are declaring them const, you will have no problems with the value of the variable, but you may have problems if you are taking its address for some comparison or something, which for different modules would be different addresses.

This would not occur with the non-inline variable, since you should export the variable from one shared module, and reference it from all the other modules, having exactly one instance for the whole program.

like image 109
LoPiTaL Avatar answered Feb 07 '23 09:02

LoPiTaL


A variable declared inline has the same semantics as a function declared inline, it can be defined, identically, in multiple translation units, must be defined in every translation unit in which it is used, and the behavior of the program is as if there was exactly one variable.

struct MyClass
{
    static const int sValue;
};
inline int const MyClass::sValue = 777;

Or even:

struct MyClass
{
    inline static const int sValue = 777;
};

Also, note that constexpr variables are inline implicitly, so there's no need to use constexpr inline myVar = 10;.

(ref.)

like image 34
Mayur Avatar answered Feb 07 '23 09:02

Mayur