Одна из моих главных претензий к C ++ заключается в том, насколько трудно на практике передавать объекты библиотеки std за пределы динамической библиотеки (т.е. dll / so).
Библиотека std часто только для заголовков. Что отлично подходит для выполнения некоторых потрясающих оптимизаций. Однако для dll они часто создаются с различными настройками компилятора, которые могут влиять на внутреннюю структуру / код контейнеров библиотеки std. Например, в MSVC одна dll может собираться с включенной отладкой итератора, а другая - без него. У этих двух библиотек могут возникнуть проблемы, связанные с передачей стандартных контейнеров. Если я представлю std::string
в своем интерфейсе, я не могу гарантировать, что код, для которого клиент использует std::string
, точно совпадает с кодом моей библиотеки std::string
.
Это приводит к трудностям при отладке, головным болям и т. Д. Вы либо жестко управляете настройками компилятора в своей организации, чтобы предотвратить эти проблемы, либо используете более простой интерфейс C, который не будет иметь этих проблем. Или укажите своим клиентам ожидаемые параметры компилятора, которые они должны использовать (что отстой, если другая библиотека указывает другие параметры компилятора).
Мой вопрос заключается в том, пытался ли C ++ 11 что-либо сделать, чтобы решить эти проблемы?
DLL
с. Между темSO
он всегда работал просто отлично.Ответы:
Вы правы в том, что в любом общедоступном API C ++ лучше избегать всего, что связано с STL, а именно чего-либо из сторонней библиотеки. Вы также хотите следовать длинному списку правил по адресу http://www.ros.org/reps/rep-0009.html#definition, чтобы запретить разрыв ABI, что делает программирование общедоступных API C ++ рутинным занятием.
И ответ относительно C ++ 11 - нет, этот стандарт не касается этого. Более интересно, почему нет? Ответ в том, что C ++ 17 очень трогает это, и для реализации модулей C ++ нам нужны экспортированные шаблоны для работы, и для этого нам нужен компилятор типа LLVM, такой как clang, который может записать полный AST на диск, а затем выполнять поиск, зависящий от вызывающего, для обработки множества случаев нарушения ODR в любом крупном проекте C ++, который, кстати, включает в себя множество кода GCC и ELF.
Наконец, я вижу много комментариев MSVC о ненависти и про-GCC. Они очень дезинформированы - GCC на ELF принципиально и безвозвратно неспособен произвести корректный и правильный код C ++. Причин для этого много и легион, но я быстро процитирую один пример: GCC на ELF не может безопасно создавать расширения Python, написанные с использованием Boost.Python, где в Python загружено более одного расширения на основе Boost.Python. Это связано с тем, что ELF с его глобальной таблицей символов C просто неспособна предотвратить нарушения ODR, вызывающие сбои, тогда как PE и MachO, а также предлагаемая спецификация модулей C ++ используют таблицы символов для каждого модуля - что, кстати, также означает значительно более быстрое время инициализации процесса. И есть еще много проблем: посмотрите на StackOverflow, на который я недавно ответилhttps://stackoverflow.com/questions/14268736/symbol-visibility-exceptions-runtime-error/14364055#14364055, например, где выбросы исключений в C ++ безвозвратно фундаментально нарушены в ELF.
Последний пункт: что касается взаимодействия различных STL, это большая боль для многих крупных корпоративных пользователей, пытающихся смешать сторонние библиотеки, которые тесно интегрированы с некоторыми реализациями STL. Единственное решение - это новый механизм для C ++ для обработки взаимодействия STL, и, хотя они и есть, вы также можете исправить взаимодействие с компилятором, чтобы вы могли (например) смешивать MSVC, GCC и clang скомпилированные объектные файлы, и все это просто работает , Я бы посмотрел на C ++ 17 и посмотрел, что будет в ближайшие несколько лет - я был бы удивлен, если бы ничего не произошло.
источник
В спецификации никогда не было этой проблемы. Это потому, что у него есть понятие, называемое «одно правило определения», которое требует, чтобы каждый символ имел ровно одно определение в рабочем процессе.
Windows DLL нарушают это требование. Вот почему есть все эти проблемы. Так что это решать Microsoft, а не комитет по стандартизации C ++. У Unix никогда не было этой проблемы, потому что общие библиотеки там работают по-другому и по умолчанию соответствуют одному правилу определения (вы можете явно нарушить его, но вы, очевидно, делаете это только в том случае, если знаете, что можете себе это позволить, и вам нужно выжать несколько дополнительных циклов).
Библиотеки Windows нарушают одно правило определения, потому что:
Unix, использующий экспорт в формате ELF, неявно импортирует все экспортированные символы, чтобы избежать первой проблемы, и не проводит различие между статически и динамически разрешаемыми символами до времени статической связи, чтобы избежать второй.
Другая проблема связана с флагами компилятора. Эта проблема существует для любой программы, состоящей из нескольких модулей компиляции, динамические библиотеки не должны быть задействованы. Однако в Windows все намного хуже. В Unix на самом деле не имеет значения, статически или динамически вы связываете, никто в любом случае статически не связывает стандартную среду выполнения (в Linux это может быть даже недопустимо), и нет специальной среды выполнения отладки, поэтому достаточно одной сборки. Но то, как Microsoft реализовала статическое и динамическое связывание, время отладки и выпуска и некоторые другие опции, означает, что они вызвали комбинаторный взрыв необходимых вариантов библиотеки. Снова проблема платформы, а не проблема языка C ++.
источник
Нет.
Продолжается большая работа по замене системы заголовков, функция, которая называется Модули и которая может повлиять на это, но, конечно, не очень большая.
источник