анонимные пространства имен и правило одного определения

Нарушаю ли я правило одного определения со следующей программой?

// foo.hpp
#ifndef FOO_HPP_
#define FOO_HPP_

namespace {
   inline int foo() {
       return 1;
   }
}

inline int bar() {
    return foo();
}
#endif
//EOF

и

// m1.cpp

#include "foo.hpp"

int m1() {
    return bar();
}

//EOF

и

// m2.cpp

#include "foo.hpp"

int m2() {
    return bar();
}

//EOF

и, наконец,

// 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

В вышесказанном обратите внимание, что foo() определяется в анонимном пространстве имен, поэтому я ожидаю, что каждая единица перевода m1.cpp и m2.cpp получит свою версию, поэтому нарушения ODR нет. С другой стороны, bar() — это просто старая встроенная функция, которая вызывает 2 разных foos. То есть это нарушает УСО, верно?

Обновление: Ранее у меня были макросы в определении foo, которые изменяли возвращаемое значение, и каждый из m1 и m2 определял макрос по-разному, прежде чем включить foo.hpp. (И в этом предыдущем примере g++ создаст двоичный файл, который выводит (i+j) со значением, отличным от ожидаемого.) Но на самом деле эта программа нарушает ODR, даже если тело foo() идентично.

16
задан Lambdageek 18 November 2011 в 21:19
поделиться