Совместимо ли изменение типа указателя закрытой переменной-члена в двоичном классе интерфейса? - PullRequest
4 голосов
/ 07 октября 2019
class Type1;
class Type2;
class __declspec(dllexport) Foo
{
  public:
    Foo();

  private:
  Type1 * m_p1;
  Type2 * m_p2;
};

Могу ли я заменить Type1 на Type3 без нарушения бинарной совместимости?

Справочная информация: К сожалению, в этом классе не используется идиома pimpl. Чтобы исправить это, я хочу заменить указатель m_p1 указателем pimpl.

Использование Visual Studio 2010, Windows 7 и 10.

1 Ответ

2 голосов
/ 07 октября 2019

Невозможно получить доступ к m_p2 на стороне вызывающего абонента из предоставленного примера кода.

Даже в этом случае это очень сильно нарушает технические термины ABI.

Но еслипредположение верно (100% уверено, что m_p2 не каким-то образом выставлено), тогда ABI сломается, только если изменение указанного типа может изменить макет класса.

Хотя это может показаться немного странным - дажекогда невозможно дать гарантию на уровне языка с ++.

Поэтому необходимо проверить, изменились ли макеты между двумя версиями для конкретной настройки. Это можно проверить с помощью чего-то вроде:

Foo* p = 0;
&p.m_p1;//offset to m_p1 (make a static member function for the check itself)

Поскольку в Foo нет виртуальных функций, нам, к счастью, не нужно беспокоиться об этом для этого класса - в противном случае это должно быть также проверено, чтобы быть абсолютноконечно.

Единственное, что осталось, это любые возможные имена, которые можно было бы оставить - которые, конечно, все еще невозможно изменить, - но само по себе не должно нарушать ABI.

...