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

Основанием для встроенных пространств имен 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?


person meastp    schedule 21.04.2015    source источник


Ответы (1)


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

Протестировано под 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, вы не можете просто заменить свою библиотеку на новую со встроенными пространствами имен. Я не буду ожидать, что какой-то другой компилятор сделает это по-другому (сохраните бинарную совместимость со встроенными пространствами имен).

person lisyarus    schedule 22.04.2015
comment
Это говорит о том, что ответ на вопрос положительный, при условии, что вы все время используете встроенные пространства имен (начиная с версии 1). - person Nemo; 28.04.2017