Нарушение ODR из-за анонимного пространства имен в заголовке - PullRequest
0 голосов
/ 09 апреля 2020

Из прочтения стандарта я не смог выяснить, нарушает ли ODR следующий код:

// a.h
#ifndef A_HEADER_FILE
#define A_HEADER_FILE

namespace {
int v;
}

inline int get_v() { return v; }

#endif // A_HEADER_FILE

// a.cpp
#include "a.h"

void f() {
  int i = get_v();
  // ...
}

// b.cpp
#include "a.h"

void g() {
  int i = get_v();
  // ...
}

(Источник: https://wiki.sei.cmu.edu/confluence/display/cplusplus/DCL59-CPP.+Do+not+define+an+unnamed+namespace+in+a+header+file)

Предположительно, get_v() ссылается на разные переменные в каждой единице перевода, поэтому нарушает ODR.

Этот ответ: Встроенные функции и внешняя связь говорит, что inline ослабляет ODR, поэтому я не уверен, почему это все еще ошибка?

Может кто-нибудь связать меня с тем, где в стандарте указано, является ли это нарушением ODR или нет?

1 Ответ

6 голосов
/ 09 апреля 2020

Функция inline может иметь несколько определений (C ++ 17 [basi c .def.odr] / 6). В этом смысле функции inline могут использоваться для предотвращения нарушений ODR. Однако множественные определения функции inline должны соответствовать друг другу. Для уточнения c, [basi c .def.odr] /6.2 гласит:

в каждом определении D соответствующие имена, найденные в соответствии с 6.4, должны относиться к сущность, определенная в определении D, или должна ссылаться на ту же сущность [...] [некоторые исключения]

Множественные определения get_v относятся к переменной v , но v не определено в get_v. Следовательно, требуется, чтобы каждое определение get_v ссылалось на одну и ту же переменную v. Это не тот случай, так как каждая единица перевода имеет свой v. Таким образом, ODR нарушается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...