Inline variables become separate entities for each translation unit

Asked 1 years ago, Updated 1 years ago, 263 views

The inline variable inline structure {intx;}y; using an unnamed structure has a different entity (with different addresses) for each translation unit and cannot be shared beyond the translation unit.
Why does it become a different entity?

a.cpp

#include<cstdio>

// NG
inline structure { intx;}y;
// OK.
inline int x;
inline structure S {intx;}z;

void b();

int main()
{
    b();

    // NG
    printf("main:%d\n",++y.x);
    // OK.
    printf("main:%d\n",++x);
    printf("main:%d\n",++z.x);
}

b.cpp

#include<cstdio>

// NG
inline structure { intx;}y;
// OK.
inline int x;
inline structure S {intx;}z;

void b()
{
    printf("b:%d\n",++y.x);
    printf("b:%d\n",++x);
    printf("b:%d\n",++z.x);
}
$clang++a.cppb.cpp-Wall-Wextra-std=c++17

Results

b:1
b:1
b:1
main —1
main —2
main —2

Tried Environment:

  • clang15 (-std=c++17)
  • gcc12 (-std=c++17)

c++

2022-12-28 00:16

1 Answers

An unnamed structure has no external linkage.
Therefore, different units of translation are considered different entities.

Answer in English:
c++-Why does an unnamed structure inline variable not have the same address in every translation unit?-Stack Overflow

Let's just ignore the inline specifier.Imagine that there was no inline specifier.Your code will still produce the same results.The reason lies in the class-type's own linkages.

[basic.link]

8. Certain types have links only if:

  • If the class or enumeration type is named (or has a name for the purpose of the link ([dcl.typedef]) and has a link in its name.
  • If you are an unknown class or an unknown enumeration that is a member of a class with a link, or
  • Specificization of class template (clause [temp]) 35.
  • Basic type.
  • Composite type other than class or enumeration, consisting only of types with links.
  • This is the cv-qualified version of the type with the link.

A type without a connection shall not be used as a variable or function type with an external connection unless:

  • If the entity has a C-language link.
  • If the entity is declared in an unknown namespace, or
  • If the entity is not odr-used or is defined in the same translation unit.

[Note: In other words, a type without a link includes a class or enumeration that cannot be named outside its translation unit.Substances with external links declared using this type cannot correspond to other entities of the program's other translation units, so odr-used must be defined in the translation unit.Note that a class with a linkage may include members with a mold without a linkage, and the typeef name is ignored in determining whether the type has a linkage.]

As you can see, there is no link for the class type used.In other words, the quoted paragraph uses an odr-use variable (with an external link), so in order for the code to be eligible, it must be defined in the same translation unit as it is used.In other words, different translation units containing the header will have different definitions.

After all, these definitions cannot be of the same object, whether inline or not.Therefore, you will eventually see a different address.


2022-12-28 02:36

If you have any answers or tips


© 2024 OneMinuteCode. All rights reserved.