Подтвердить что ты не робот

Разве динамические библиотеки нарушают стандарт С++?

Стандарт С++ 3.6.3:

Деструкторы для инициализированных объектов статической продолжительности вызываются в результате возврата из main и в результате вызова exit

В Windows у вас есть FreeLibrary, а у linux есть dlclose, чтобы выгрузить динамически связанную библиотеку. И вы можете вызвать эти функции, прежде чем вернуться с основного.

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

Означает ли это, что это нарушает стандарт С++, поскольку эти деструкторы запущены преждевременно?

4b9b3361

Ответ 1

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

Ответ 2

Это бессмысленный вопрос. Стандарт С++ не говорит, что делать или делать dlclose.

Если бы стандарт включал спецификацию для dlclose, это, безусловно, указывало бы, что dlclose является исключением из 3.6.3. Таким образом, 3.6.3 не будет нарушаться, поскольку это будет задокументированное исключение. Но мы не можем этого знать, поскольку он не распространяется на него.

Какое влияние dlclose на гарантии в стандарте С++ просто выходит за рамки этого стандарта. Ничто dlclose не может нарушить стандарт С++, поскольку стандарт ничего не говорит об этом.

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

Ответ 3

Parapura, может быть полезно помнить, что стандарт С++ - это определение языка, которое накладывает ограничения на то, как компилятор преобразует исходный код в объектный код.

Стандарт не накладывает ограничений на операционную систему, аппаратное обеспечение или что-то еще.

Если пользователь отключает свою машину, это нарушение стандарта С++? Конечно нет. Должен ли стандарт говорить "если пользователь отключает устройство" как "исключение" для каждого правила? Это было бы глупо.

Аналогично, если операционная система убивает процесс или заставляет освобождать некоторые системные ресурсы или даже позволяет сторонней программе сжимать ваши структуры данных - это не является нарушением стандарта С++. Это может быть ошибкой в ​​ОС, но определение языка С++ остается неповрежденным.

Стандарт является обязательным только для компиляторов и заставляет полученный исполняемый код иметь определенные свойства. Тем не менее, это не связывает поведение во время выполнения, поэтому мы тратим столько времени на обработку исключений.

Ответ 4

Я беру это, чтобы быть немного открытым вопросом.

Я бы сказал так: стандарт определяет только, что такое программа. И программа ( "размещенная", я должен добавить) представляет собой набор скомпилированных и связанных единиц перевода, который имеет уникальную точку входа main.

В общей библиотеке нет такой вещи, поэтому она даже не представляет собой "программу" в смысле стандарта. Это всего лишь куча связанного исполняемого кода без какого-либо "потока". Если вы используете привязку времени загрузки, библиотека становится частью программы, и все как ожидается. Но если вы используете привязку времени исполнения, ситуация другая.

Следовательно, вам может понравиться просмотреть его следующим образом: глобальные переменные в связанном с runtime совместном объекте являются по существу динамическими объектами, которые создаются динамическим загрузчиком и которые уничтожаются при выгрузке библиотеки. Тот факт, что эти объекты объявлены как глобальные объекты, не меняет этого, поскольку объекты не являются частью "программы" в этой точке.

Ответ 5

Если это нарушает стандарт, кто нарушитель? Компилятор С++ не может считаться нарушителем (поскольку вещи загружаются динамически через вызов библиотеки); таким образом, он должен быть поставщиком функциональных возможностей динамической загрузки, а также поставщиком ОС. Поставщики ОС связаны стандартом С++ при разработке своих систем? Это определенно кажется вне рамки стандарта.

Ответ 6

Или для другой перспективы, рассмотрите сама библиотека как отдельная программа, предоставляющая какой-то сервис. Когда эта программа завершается (независимо от того, что библиотека выгружается), тогда все связанные служебные объекты также должны исчезнуть, статические или нет.

Ответ 7

Это всего лишь одна из тонны и тонны "расширений" для платформы (для целевого компилятора, архитектуры, ОС и т.д.), которые доступны. Все это "нарушает" стандарт различными способами. Но есть только одно ожидаемое последствие для отклонения от стандартного С++: вы больше не переносите. (Если вы не делаете много #ifdef или что-то еще, но все же этот конкретный код заблокирован на этой платформе).

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