анонимные пространства имен и одно определение правила - PullRequest
16 голосов
/ 31 октября 2011

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

// 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 разных foo s.То есть он нарушает ODR, верно?

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

Ответы [ 2 ]

8 голосов
/ 31 октября 2011

Это нарушает ODR.См. П. 3.2 / 5, в котором говорится о внешних встроенных функциях (bar):

в каждом определении D соответствующие имена, просмотренные в соответствии с 3.4, должны ссылаться на объект, определенный в определенииof D, или должен относиться к одной и той же сущности ...

В этом случае bar относится к двум различным версиям foo, нарушая тем самым правило.

6 голосов
/ 31 октября 2011

Да, это определение bar() нарушает правило единого определения.Вы создаете несколько определений, каждое из которых вызывает отдельную функцию с именем foo().

Как вы говорите, это будет нарушением, даже если все версии foo() идентичны, поскольку они по-прежнему являются разными функциями..

...