Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are inline variables unique across boundaries?

Tags:

This is a follow up of this question.
As mentioned in the comments to the answer:

An inline variable has the property that - It has the same address in every translation unit. [...] Usually you achieved that by defining the variable in a cpp file, but with the inline specifier you can just declare/define your variables in a header file and every translation unit using this inline variable uses exactly the same object.

Moreover, from the answer itself:

While the language does not guarantee (or even mention) what happens when you use this new feature across shared libraries boundaries, it does work on my machine.

In other terms, it isn't clear if an inline variable is guaranteed to be unique across boundaries when shared libraries are involved. Someone proved empirically that it works on some platforms, but it isn't properly an answer and it could just break everything on other platforms.

Is there any guarantee regarding the uniqueness of an inline variable when it is used across boundaries or is it simply an implementation detail that I should not rely on?

like image 677
skypjack Avatar asked Jul 17 '18 06:07

skypjack


People also ask

What does it mean to inline a variable?

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.

What is an inline substitution?

In ModelBuilder, the value or dataset path of a variable can be substituted for another variable by enclosing the substituting variable name in percent signs (%VariableName%). Substituting variables in this manner is called inline variable substitution.

What does static inline mean?

In C, static means the function or variable you define can be only used in this file(i.e. the compile unit) So, static inline means the inline function which can be used in this file only.


2 Answers

This is how I interpret the standard. According to basic.link/1:

A program consists of one or more translation units linked together.

It doesn't say anything about static linking nor dynamic linking. A program is translation units linked together. It doesn't matter if the linking is done in two steps (first create a .dll/.so, and then the dynamic linker links all dynamic libs + executable together).

So, in my interpretation, it doesn't matter whether a program is dynamically or statically linked, the implementation should behave the same: a class static variable should be unique (no matter whether it's inline or not).

On Linux, this is true.

On Windows, this doesn't work in all circumstances, so in my interpretation, it violates the standard in these circumstances (if you create a separate .dll, which contains the static, non-inline variable, and all other .dll's and the exe refers to this variable, it works).

like image 158
geza Avatar answered Sep 22 '22 20:09

geza


C++ currently does not have a concept of shared libraries. So the way inline behaves across shared libraries would be implementation- and platform-specific.

The fact that [basic.link]/1 states that "A program consists of one or more translation units linked together." doesn't quite mean that a program linked together with another, already linked module, should behave the same.

A lot of proposals have been submitted over the years to rectify the situation (N1400, N1418, N1496, N1976, N2407, N3347, N4028), none of which took off the ground. It's just hard to implement in a generic way, and C++ generally tries to stay out of implementation details. As GCC put it:

For targets that do not support either COMDAT or weak symbols, most entities with vague linkage are emitted as local symbols to avoid duplicate definition errors from the linker. This does not happen for local statics in inlines, however, as having multiple copies almost certainly breaks things.

MSVC does not expose any symbols by default. Any "external" symbol needs to be explicitly declared with a platform-specific __declspec(dllexport). One can't claim Windows to be incompatible with C++ because of this. None of C++ rules are violated here, because there aren't any.

like image 39
rustyx Avatar answered Sep 20 '22 20:09

rustyx