Могат ли вградените пространства от имена да се използват за поддържане на обратна съвместимост в споделена библиотека?

Обосновката за вградените пространства от имена на C++ е едновременно изходен код и двоична съвместимост (вижте статията на Herb Sutter, свързана в 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