Можно ли использовать встроенные пространства имен для обеспечения обратной совместимости в общей библиотеке?

Обоснованием встроенных пространств имен C ++ является как исходная, так и двоичная совместимость (см. Статью Херба Саттера, приведенную в N2535), но я не смог найти хороших примеров хранение двоичная совместимость для существующих библиотек при внедрении встроенных пространств имен или, если это возможно.

(для получения дополнительной информации и примеров совместимости источника см. этот вопрос)

(для решения связанной проблемы, используя встроенное пространство имен для введения несовместимости, см. этот вопрос)

Если это наша текущая библиотека (например, mylib.dll), которая используется совместно с клиентами и должна быть стабильной:

struct ModelA
{
/* (...) lots of stuff */
};

struct ModelB
{
/* (...) lots of stuff */
};

Можем ли мы использовать встроенные пространства имен для введения новых версий структур / классов, не ломая клиентов (т. Е. Заменить только файл общей библиотеки (mylib.dll), без необходимости перекомпиляции)?

inline namespace mylib
{

inline namespace v1
{
struct ModelA
{
/* (...) lots of stuff */
};
} // end namespace v1

namespace v2
{
struct ModelA
{
/* (...) lots of stuff + newstuff */
};
} // end namespace v2

struct ModelB
{
/* (...) lots of stuff */
};

} // end namespace mylib

Если нет, будет ли он работать без встроенного пространства имен mylib?

4

Решение

Не совсем ответ на ваш вопрос, но, вероятно, может привести к ответу.

Протестировано под gcc 4.8.2 с двумя простыми источниками:

namespace n1
{
void f1 (int);

inline namespace n2
{
void f2 (int);
}
}

void f (int x)
{
n1::f1(x);
n1::f2(x);
}

И без встроенного пространства имен:

namespace n1
{
void f1 (int);
void f2 (int);
}

void f (int x)
{
n1::f1(x);
n1::f2(x);
}

Затем проверял искаженные имена символов в скомпилированных объектных файлах, используя objdump -t,

Результаты по первой версии (с встроенное пространство имен):

_ZN2n12f1Ei
_ZN2n12n22f2Ei

Вторая версия (без встроенное пространство имен):

_ZN2n12f1Ei
_ZN2n12f2Ei

Вы можете видеть, что искалеченное имя f2 отличается (первый включает в себя название n2 Пространство имен). Это означает, что если вы используете gcc, вы не можете просто заменить свою библиотеку новой с встроенными пространствами имен. Я не ожидаю, что какой-то другой компилятор сделает это по-другому (сохранит двоичную совместимость со встроенными пространствами имен).

2

Другие решения