Your analysis is correct, but doesn't necessarily imply uselessness. Even if most compilers do automatically inline functions (reason #1), it's best to declare inline
just to describe intent.
Disregarding interaction with inline
, static
functions should be used sparingly. The static
modifier at namespace scope was formerly deprecated in favor of unnamed namespaces (C++03 §D.2). For some obscure reason that I can't recall it was removed from deprecation in C++11 but you should seldom need it.
So, Practically marking a function static and inline both has no use at all. Either it should be static(not most preferred) or inline(most preferred),
There's no notion of preference. static
implies that different functions with the same signature may exist in different .cpp
files (translation units). inline
without static
means that it's OK for different translation units to define the same function with identical definitions.
What is preferred is to use an unnamed namespace instead of static
:
namespace {
inline void better(); // give the function a unique name
}
static inline void worse(); // kludge the linker to allowing duplicates
Without inline
, it's explicitly stated as only a declaration. As specified in [class.static.data]/2
The declaration of a non-inline static data member in its class
definition is not a definition and may be of an incomplete type other
than cv void. The definition for a static data member that is not
defined inline in the class definition shall appear in a namespace
scope enclosing the member's class definition.
The rationale is most probably to keep legacy code intact and valid. Recall that we could initialize integral constants in the class definition itself since about forever. But odr-using them still required an out-of-class definition in some translation unit.
So to makes such variables implicitly inline could be problematic in existing codebases. The committee is always thinking about backwards compatibility when core language features are added.
For instance, consider this valid C++03 class definition:
struct foo {
static const int n = 3;
double bar[n];
};
n
can be used as a constant expression to define the extent of bar
, and it's not considered an odr-use. Nowadays we'd write it as constexpr
1, however that above is still valid. But there may be cases were n
would have to be odr-used (imagine its address taken, or a reference bound to it, etc). They are probably not many, and probably not common, but certain API's have crazy requirements that would end up necessitating this
const int foo::n;
to appear in some translation unit.
Now, if static inline int i = 8;
was suddenly implicitly inline
, the definition above (that is in an existing code base) would be an odr-violation. Now previously well-formed code, is ill-formed. So it's best to allow only explicit inline
to take effect here, since only new code will actually have it.
1 One could argue that static constexpr
variables may have the same issue (and yet they are implicitly inline). But IIRC their original wording allowed this change without potentially breaking existing code. It was essentially already "inline" by everything but name.
Best Answer
Pretty much.
static
has an effect that interferes withinline
. The C++ standard states thatAnd the
static
qualifier imposes internal linkage, so the single address guarantee does not have to hold. Now, a name with internal linkage in different translation units is meant to denote different object in each TU, so getting multiple distincti
's is intended.All in all, the
static
negates theinline
. And there is no point to having astatic inline
variable over a plainstatic
one.