Динамические библиотеки нарушают стандарт C ++? - PullRequest
21 голосов
/ 04 ноября 2011

Стандарт C ++ 3.6.3 состояния

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

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

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

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

Ответы [ 7 ]

23 голосов
/ 04 ноября 2011

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

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

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

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

19 голосов
/ 07 ноября 2011

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

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

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

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

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

11 голосов
/ 04 ноября 2011

Я воспринимаю это как открытый вопрос.

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

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

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

2 голосов
/ 04 ноября 2011

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

1 голос
/ 09 ноября 2011

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

1 голос
/ 08 ноября 2011

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

0 голосов
/ 14 ноября 2011

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...