namespace anonyme dans un .h
Pour ne pas polluer ce thread,
http://www.developpez.net/forums/sho...d.php?t=501525
je poste dans un nouveau
Citation:
Citation:
Envoyé par Emmanuel Deloget
Quand au namespace anonyme, il est équivalent à créer une fonction statique (c'est à dire locale à l'unité de compilation). Ce n'est pas nécessaire, mais ça peut quand même être utile.
Appelé depuis un template non exporté (défini dans un en-tête), ça a pour seule utilité d'avoir un comportement indéfini.
Ma question est pourquoi?
ODR - One Definition Rule
Citation:
Envoyé par
Mongaulois
Ma question est pourquoi?
(Mettons l'aspect "template" de coté, il ne sert à rien ici.)
Soit le programme :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| Header.hpp :
namespace { // espace référentiel anonyme
void rien_anon() {
}
}
static void rien_static() {
}
inline void multiply_defined() {
rien_anon(); // comportement indéfini
rien_static(); // comportement indéfini
}
Toto.cpp :
#include "Header.hpp"
Main.cpp :
#include "Header.hpp"
int main() {
} |
Ce programme (complet) a un comportement indéfini, parce que la définition de multiply_defined() viole l'ODR (One Definition Rule) : multiply_defined() est définie deux fois, et les deux définitions ne correspondent pas, en effet :
Si on regarde la définition d'un espace référentiel anonyme, ceci équivaut à :
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| Toto.cpp :
namespace __anon_namespace_Toto_cpp {}
using namespace __anon_namespace_Toto_cpp;
namespace __anon_namespace_Toto_cpp {
void rien_anon() {
}
}
static void rien_static() { // (1)
}
inline void multiply_defined() {
rien_anon(); // appel de __anon_namespace_Toto_cpp::rien_anon()
rien_static(); // appel de (1)
}
Main.cpp :
namespace __anon_namespace_Main_cpp {}
using namespace __anon_namespace_Main_cpp;
namespace __anon_namespace_Main_cpp {
void rien_anon() {
}
}
static void rien_static() { // (2)
}
inline void multiply_defined() {
rien_anon(); // appel de __anon_namespace_Main_cpp::rien_anon()
rien_static(); // appel de (2)
}
int main() {
} |
On voit que multiply_defined() est défini deux fois comme appelant des fonctions différentes.