Est-ce que je viole la règle de définition unique avec le programme suivant?namespaces anonymes et la règle de définition unique
// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_
namespace {
inline int foo() {
return 1;
}
}
inline int bar() {
return foo();
}
#endif
//EOF
et
// m1.cpp
#include "foo.hpp"
int m1() {
return bar();
}
//EOF
et
// m2.cpp
#include "foo.hpp"
int m2() {
return bar();
}
//EOF
et enfin
// main.cpp
#include <iostream>
int m1();
int m2();
int main(int, const char* [])
{
int i = m1();
int j = m2();
std::cout << (i+j) << std::endl;
return 0;
}
// EOF
Dans ce qui précède, notez que foo()
est définie dans un espace de noms anonyme, donc je pense que chaque unité de traduction m1.cpp
et m2.cpp
aura sa propre version, donc il n'y a pas de violation de l'ODR. D'autre part, bar()
est juste une vieille fonction en ligne simple qui arrive à appeler 2 différents foo
s. Donc, cela viole l'ODR, n'est-ce pas?
Mise à jour: Auparavant, j'avais des macros dans la définition de foo
qui a changé la valeur il est revenu et chacun défini la macro différemment m1
et m2
avant d'inclure foo.hpp
. (Et avec cet exemple précédent, g++
produirait un binaire qui produirait (i+j)
avec une valeur autre que celle que vous attendez.) Mais en fait ce programme viole l'ODR même si le corps de foo()
est identique.
Je pense que cela illustre clairement pourquoi l'utilisation d'espaces de noms anonymes ou de fonctions statiques dans les fichiers d'en-tête pose des problèmes :) –