¿Estoy violando la regla de una definición con el siguiente programa?espacios de nombres anónimos y la regla de una definición
// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_
namespace {
inline int foo() {
return 1;
}
}
inline int bar() {
return foo();
}
#endif
//EOF
y
// m1.cpp
#include "foo.hpp"
int m1() {
return bar();
}
//EOF
y
// m2.cpp
#include "foo.hpp"
int m2() {
return bar();
}
//EOF
y finalmente
// 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
En lo anterior, cabe destacar que foo()
se define en un espacio de nombres en el anonimato, por lo que espero que cada uno la unidad de traducción m1.cpp
y m2.cpp
tendrá su propia versión, por lo que no habrá violación de la ODR. Por otro lado, bar()
es simplemente una vieja función en línea que llama a 2 diferentes foo
s. Entonces viola la ODR, ¿verdad?
Actualización: Anteriormente he tenido macros en la definición de foo
que cambió el valor volvió y cada uno de m1
y m2
definida la macro de forma diferente antes de incluir foo.hpp
. (Y con ese ejemplo anterior, g++
produciría un archivo binario que generaría (i+j)
con un valor diferente al que cabría esperar). Pero, de hecho, este programa infringe el ODR, incluso si el cuerpo de foo()
es idéntico.
Creo que esto ilustra claramente por qué el uso de espacios de nombres anónimos o funciones estáticas en archivos de encabezado trae problemas :) –