Предположим, что у меня есть две единицы компиляции в одной программе, каждая из которых объявляет не встроенную функцию с одинаковыми сигнатурами, но отличается по реализации, например
// a.cpp
namespace internal {
int foo(int a) {
return a+1;
}
}
int main() {
}
и
// b.cpp
namespace internal {
int foo(int b) {
return b+2;
}
}
Скомпилировав / связав это (g ++ 4.8.3 с -std=c++11
), я получаю ошибку
b.cpp:(.text+0x0): multiple definition of `internal::foo(int)'
, что вполне ожидаемо, поскольку, насколько я понимаю, это просто нарушение одно правило определения :
Одно и только одно определение каждой не встроенной функции или переменной, используемой в odr (см. ниже), требуется для отображения во всемПрограмма (включая любые стандартные и пользовательские библиотеки).
Теперь, изменив namespace internal
в безымянное пространство имен, ошибка исчезнет.Интуитивно, это имеет смысл для меня, так как я меняю функцию с внешнюю на внутреннюю связь :
Любое из следующих имен, объявленных в области имен, имеет внешнюю связь, если толькопространство имен неименовано или содержится в безымянном пространстве имен (начиная с C ++ 11): переменные и функции, не перечисленные выше (то есть функции, не объявленные статическими [...]) ...
и
[A] Все имена, объявленные в безымянном пространстве имен или в пространстве имен в безымянном пространстве имен, даже если они явно объявлены extern, имеют внутреннюю связь.
Однако я былневозможно найти что-либо в одном правиле определения, которое освобождает от него функции с внутренней связью.Поэтому мой вопрос: правильны ли мои интуитивные рассуждения, или я все еще нарушаю одно правило определения с функциями, которые имеют внутреннюю связь (а компилятор / компоновщик просто больше не сообщает об этом)?Кроме того, где в стандарте (или cppreference.com :)
) указано, все ли в порядке?