Нарушение ODR при связывании статической и динамической библиотеки - PullRequest
2 голосов
/ 11 апреля 2019

Будет ли связывание статической библиотеки cpp и динамической библиотеки cpp, содержащей разные версии boost, нарушением ODR?

Я работаю над приложением для iphone.Для окончательного выполнения мне нужно связать статическую библиотеку, скажем, libstatic1.a, и динамическое фреймворк, скажем, libdyanamic1.

libstatic1.a содержит некоторую версию boost, скажем, boost 1.x, а libdynamic1 содержит другую версию boost, скажемповысить 1.й.Теперь будет ли финальный исполняемый файл, который связывает их обоих, нарушать правило ODR?

Видимость символов в libdynamic1: я проверил символы, присутствующие в libdynamic1, используя nm -g -C libdynamic1, и заметил, что в списке присутствуют символы Boost Threadpool и Boost Filesystem..

Если я нарушаю ODR, какие у меня есть способы справиться с ситуацией?(До сих пор я тестировал исполняемый файл на нескольких устройствах и не испытывал никаких проблем.)

1 Ответ

1 голос
/ 11 апреля 2019

Стандарт говорит только о «программах», где «программа» - это набор единиц перевода, «связанных вместе», каждая из которых состоит из последовательности объявлений [basic.link] . Спорить с ODR, который касается только «программ», когда дело касается вопросов, связанных с динамическими библиотеками, не так уж и просто. Поскольку требуется, чтобы «программа» содержала main функцию [basic.start.main] / 1 , библиотека динамических ссылок, как правило, сама по себе не считается «программой».

Строго говоря, я думаю, что динамическая библиотека должна рассматриваться как просто еще один набор единиц перевода, которые «связаны» с остальными для формирования окончательной программы. Таким образом, программа действительно будет завершена только после того, как все образы будут загружены в память и динамическое связывание будет завершено (динамическое связывание во время выполнения может еще больше усложнить ситуацию, но, думаю, здесь это можно проигнорировать). В этом смысле программа, описанная в вашем вопросе (связывающая статическую и динамическую библиотеки, где каждая использует свою версию boost), почти наверняка будет нарушать ODR, поскольку у вас будет несколько блоков перевода, например, используя различные определения одинаковых сущностей [basic.def.odr] / 12 .

Однако на практике эта проблема сильно зависит от платформы и цепочки инструментов. На уровне ABI вы обычно обнаруживаете, что типы связей, которые может иметь символ, более дифференцированы, чем на уровне языка в C ++. Например, в Windows обычно требуется явно указать, какие символы следует экспортировать при создании динамической библиотеки, по умолчанию все имена являются внутренними для библиотеки. С другой стороны, в Linux на базе ELF это не совсем так. Однако может показаться, что вы можете использовать опцию -fvisibility=hidden, чтобы переключить GCC на Windows-режим по умолчанию, где ваша библиотека будет экспортировать только то, что вы явно указали. Обратите внимание, что не должен иметь какое-либо отношение к boost в интерфейсе экспорта вашей библиотеки, поскольку это, очевидно, приведет к неопределенному поведению в вашем случае & hellip;

...