La différence est le nom de l'identifiant modifié ( _ZN12_GLOBAL__N_11bE
vs _ZL1b
, ce qui n'a pas vraiment d'importance, mais les deux sont assemblés en symboles locaux dans la table des symboles (absence de .global
directive asm).
#include<iostream>
namespace {
int a = 3;
}
static int b = 4;
int c = 5;
int main (){
std::cout << a << b << c;
}
.data
.align 4
.type _ZN12_GLOBAL__N_11aE, @object
.size _ZN12_GLOBAL__N_11aE, 4
_ZN12_GLOBAL__N_11aE:
.long 3
.align 4
.type _ZL1b, @object
.size _ZL1b, 4
_ZL1b:
.long 4
.globl c
.align 4
.type c, @object
.size c, 4
c:
.long 5
.text
Quant à un espace de noms anonyme imbriqué:
namespace {
namespace {
int a = 3;
}
}
.data
.align 4
.type _ZN12_GLOBAL__N_112_GLOBAL__N_11aE, @object
.size _ZN12_GLOBAL__N_112_GLOBAL__N_11aE, 4
_ZN12_GLOBAL__N_112_GLOBAL__N_11aE:
.long 3
.align 4
.type _ZL1b, @object
.size _ZL1b, 4
Tous les espaces de noms anonymes de 1er niveau dans l'unité de traduction sont combinés les uns avec les autres, Tous les espaces de noms anonymes imbriqués de 2e niveau dans l'unité de traduction sont combinés les uns avec les autres
Vous pouvez également avoir un espace de noms imbriqué (en ligne) dans un espace de noms anonyme
namespace {
namespace A {
int a = 3;
}
}
.data
.align 4
.type _ZN12_GLOBAL__N_11A1aE, @object
.size _ZN12_GLOBAL__N_11A1aE, 4
_ZN12_GLOBAL__N_11A1aE:
.long 3
.align 4
.type _ZL1b, @object
.size _ZL1b, 4
which for the record demangles as:
.data
.align 4
.type (anonymous namespace)::A::a, @object
.size (anonymous namespace)::A::a, 4
(anonymous namespace)::A::a:
.long 3
.align 4
.type b, @object
.size b, 4
Vous pouvez également avoir des espaces de noms en ligne anonymes, mais pour autant que je sache, inline
sur un espace de noms anonyme a un effet 0
inline namespace {
inline namespace {
int a = 3;
}
}
_ZL1b
: _Z
signifie qu'il s'agit d'un identifiant mutilé. L
signifie que c'est un symbole local à travers static
. 1
est la longueur de l'identifiant b
, puis l'identifiantb
_ZN12_GLOBAL__N_11aE
_Z
signifie qu'il s'agit d'un identifiant mutilé. N
signifie qu'il s'agit d'un espace de noms 12
est la longueur du nom d'espace de noms anonyme _GLOBAL__N_1
, puis le nom de l'espace de noms anonyme _GLOBAL__N_1
, puis 1
la longueur de l'identifiant a
, a
est l'identifiant a
et E
ferme l'identifiant qui réside dans un espace de noms.
_ZN12_GLOBAL__N_11A1aE
est le même que ci-dessus, sauf qu'il y a un autre niveau d'espace de noms dedans 1A
static
dans ce contexte n'était pas obsolète ; bien que l' espace de noms sans nom soit une alternative supérieure àstatic
, il y a des cas où il échoue quandstatic
vient à la rescousse .