Есть ли магия в STL?

Позвольте мне начать с объяснения того, что я имею в виду под словом «магия». Я буду использовать два примера из Java:

  1. Каждый класс наследует (прямо или косвенно) класс Object.
  2. Перегрузка операторов не поддерживается Java, но оператор + определен для String объектов.

Это означает, что реализовать классы Object и String на чистом (*) Java невозможно. Вот что я имею в виду под «магией»: чтобы реализовать эти классы, вам понадобится специальная поддержка со стороны компилятора.

Что мне всегда нравилось в C++, так это то, что, насколько мне известно, в STL не происходит такого «волшебства», т.е. STL можно реализовать на чистом C++.

Теперь мой вопрос: это правда? Или есть части STL, которые не могут быть реализованы на чистом C++ и нуждаются в какой-то «волшебной»/специальной поддержке компилятора?


(*) Под «чистым» я подразумеваю без использования каких-либо библиотек классов.


person mtvec    schedule 26.08.2010    source источник
comment
Вопрос немного запутанный, я считаю. STL = стандартная библиотека шаблонов, написанная на чистом C++. Вам не нужно внедрять STL, потому что он уже есть. Вместо этого вы имели в виду шаблонные/общие классы? Или вы имели в виду создание экземпляра конкретного экземпляра контейнера STL?   -  person Vite Falcon    schedule 26.08.2010
comment
Программное обеспечение никогда не основывается на магии. Однако хорошее программное обеспечение может создать иллюзию «волшебства».   -  person Chubsdad    schedule 26.08.2010
comment
@Vite: я знаю, что STL является частью стандарта, но, как сказано в моей сноске, под чистым я имею в виду без каких-либо библиотек.   -  person mtvec    schedule 26.08.2010
comment
@Job: Я думаю, что путаница связана с тем, что вы используете слово «магия». Описание его как требующего поддержки компилятора/языка, скорее всего, устранит большую часть путаницы.   -  person greyfade    schedule 26.08.2010
comment
@greyfade: добавил ваше предложение. Тем не менее, я думаю, что указал, что я имею в виду под магией.   -  person mtvec    schedule 26.08.2010
comment
Я видел, как некоторые компиляторы добавляют специальные теги и творят чудеса при их интерпретации, но это всегда было так, чтобы они могли выводить более качественные предупреждения/сообщения об ошибках. В конце концов, это никак не повлияло на скомпилированный код, просто дополнительная информация для кодера (хотя многие компиляторы вообще ничего особенного не делают с STL).   -  person Grant Peters    schedule 26.08.2010
comment
Действительно хороший вопрос. +1 :)   -  person jalf    schedule 26.08.2010
comment
Любая достаточно развитая технология неотличима от магии. (А.С. Кларк)   -  person Max    schedule 26.08.2010
comment
@Job Как я уже упоминал в своем вопросе, вы имели в виду класс «шаблон», а не STL. STL означает, что это библиотека и библиотека классов. Так что ваше понятие «чистого» кажется немного запутанным.   -  person Vite Falcon    schedule 26.08.2010
comment
@Vite: Нет, я действительно имею в виду STL. Извините, но я не понимаю, что вас смущает.   -  person mtvec    schedule 26.08.2010
comment
Я думаю, ваш вопрос: можно ли реализовать STL на C++? Я думаю, более интересен более широкий вопрос: можно ли стандартные библиотеки C++ реализовать на C++? включая среду выполнения C.   -  person Jay Bazuzi    schedule 26.08.2010
comment
Отредактировано для удаления мыльницы, проголосовали за повторное открытие.   -  person bmargulies    schedule 27.08.2010
comment
@bmargulies: Почему вы удалили эту часть моего вопроса? Думаю, это хороший пример того, что я имею в виду под магией. Кроме того, насколько это субъективно?   -  person mtvec    schedule 27.08.2010
comment
@bmargulies: я сделаю откат. Я должен сказать, что считаю грубым вносить такие большие изменения в вопрос. И если вы действительно считаете, что для этого есть веская причина, пожалуйста, убедитесь, что вы не вводите никаких ошибок! Например. В первом предложении отсутствует слово, и сноска больше не упоминается. /разглагольствование. Кроме того, мое вступление не предназначено для того, чтобы быть пламенным (как вы упоминаете в своем редактировании), а просто для объяснения того, что я имею в виду под магией.   -  person mtvec    schedule 27.08.2010
comment
Иов, твой вопрос спорный. Я бы оставил это с правкой, но теперь, когда вы откатились, я снова голосую за закрытие.   -  person Aaronaught    schedule 27.08.2010
comment
@Aaronaught: Если вы считаете, что это спорно, укажите причину, чтобы я мог отредактировать его так, как мне удобно. Я все еще думаю, что вопрос очень объективен. Тот факт, что мне не нравятся данные пункты о Java, может быть спорным, хотя это всего лишь мое мнение. Я не говорю, что с Java что-то не так.   -  person mtvec    schedule 27.08.2010
comment
@Job, он был закрыт, потому что 5 человек сочли ваши жалобы на анти-Java ненужными и неуместными. После того, как он был закрыт, я отредактировал его, чтобы сделать его менее нежелательным. Теперь, когда вы откатили его, он может снова закрыться.   -  person bmargulies    schedule 27.08.2010
comment
@bmargulies: Нет, он был закрыт, потому что пять человек сочли его субъективным, а это явно не так. Вот почему я откатил ваши изменения. Теперь, если бы эти люди (включая вас) сказали бы мне, что они оскорблены тем, что вы называете жалобами против Java (вместо того, чтобы проголосовать за закрытие без слов), всех этих хлопот можно было бы избежать, и я бы удалил оскорбительную часть. (что я и сделал сейчас). Кстати, как я уже сказал в другом комментарии, я никогда не хотел звучать анти-Java. Я просто хотел объяснить, что я имею в виду под магией.   -  person mtvec    schedule 27.08.2010
comment
@Job: Ваше использование STL сбивает с толку. Еще в 1990-х годах существовала так называемая стандартная библиотека шаблонов, которая была реализована на простом C++ в том виде, в каком она существовала в то время. Большая часть STL была поглощена стандартными библиотеками C++, поэтому самой STL нет в большинстве современных реализаций. Ваш вопрос о C++0x STL абсолютно неверен; поскольку STL по существу устарел, новых его версий нет.   -  person David Thornley    schedule 27.08.2010
comment
@David: Спасибо за отзыв! Не могли бы вы предложить заменить все вхождения STL стандартной библиотекой C++?   -  person mtvec    schedule 27.08.2010
comment
@bmargulies: После быстрого просмотра записи редактирования я не вижу никаких нападок на Java. Джоб упомянул об одной функции, которая ему нравится, которая в некоторой степени есть в C++03, а в Java нет. Он не претендует на общее превосходство одной из них и даже не говорит, что не любит Java. Это самое безобидное мнение о компьютерных языках, и оно имеет достоинство быть объективным (учитывая его мнение о магии компилятора). Здесь больше аргументов, чем мне хотелось бы, но мне не ясно, виноват ли в этом Иов.   -  person David Thornley    schedule 27.08.2010
comment
@Job: я бы, наверное, описал это как часть контейнеров, итераторов и алгоритмов. Стандартная библиотека C++ требует некоторого волшебства. Например, вы не можете выполнять ввод без библиотечной подпрограммы, которая читает что-то из файла, поэтому вы не можете начать с C++ без библиотеки и написать части ввода-вывода библиотеки.   -  person David Thornley    schedule 27.08.2010
comment
@David: Но раньше я думал, что STL — это полная стандартная библиотека C++. Так что меня также интересует любая магия, необходимая в других частях, помимо контейнеров. Было бы слишком большим изменением заменить STL стандартной библиотекой?   -  person mtvec    schedule 27.08.2010
comment
@David: Обычно можно с уверенностью предположить, что, когда люди говорят STL, они имеют в виду подмножество стандартной библиотеки C ++, основанное на STL. Притворство сбитым с толку на самом деле никому ничего не дает. Да, термин STL все употребляют неправильно, и что? Человеческий мозг достаточно хорошо справляется с двусмысленностью, чтобы разобраться в ней. Я бы сказал, что STL немного удобнее, чем контейнеры, итераторы и алгоритмы, входящие в стандартную библиотеку С++...   -  person jalf    schedule 28.08.2010
comment
Ну вот и снова... Не мог бы кто-нибудь из доводчиков объяснить, почему вы считаете, что это субъективно?   -  person mtvec    schedule 30.08.2010
comment
@Job: Я хотел бы знать себя. Это похоже на вопрос программирования с твердыми и объективными ответами. Это хороший вопрос. Голосование за открытие.   -  person David Thornley    schedule 30.08.2010
comment
Первоначально я проголосовал за закрытие до последних правок. Меня устраивает эта версия вопроса, без поляризации «хорошо/плохо нравится/не нравится», поэтому я голосую за повторное открытие сейчас.   -  person Aaronaught    schedule 31.08.2010


Ответы (9)


Другими словами, было ли сделано что-нибудь для компилятора, чтобы учесть «особый случай», необходимый для работы STL?

No.

Все это было реализовано как «чистый» код C++ с использованием магии шаблонов.

Для компиляторов была проделана некоторая работа по улучшению STL (я думаю о различных оптимизациях), но в остальном нет, вы могли бы написать всю STL, если бы действительно хотели. Некоторые люди так и сделали — STLPort — это реализация, не получившая поддержку ни одного производителя компилятора.

person gbjbaanb    schedule 26.08.2010
comment
Что ж, большинству компиляторов нужно было улучшить соответствие стандартам... но да. - person ; 26.08.2010
comment
С C++ волшебство УЖЕ БЫЛО. +1 - person mlvljr; 08.10.2010
comment
-1: Это больше не правильно. Смотрите другие ответы. - person Lightness Races in Orbit; 16.09.2011

Как правильно сказал gbjbaanb, STL можно реализовать на простом C++, не полагаясь на какую-либо «магию» компилятора.

Однако, если вы покопаетесь в исходном коде STL для вашего компилятора, вы, вероятно, увидите код, который либо не является стандартным, либо который вы не должны писать сами.

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

Они также постоянно используют имена, которые вам не разрешено использовать. Например, параметры шаблона обычно имеют имена вроде _Type, которые, поскольку они начинаются со знака подчеркивания, за которым следует заглавная буква, зарезервированы для реализации. Стандартной библиотеке разрешено их использовать, а нам с вами — нет. Поэтому, если вы собираетесь написать свою собственную реализацию STL, вам придется внести некоторые незначительные изменения, но это не из-за какой-то магии, а просто для того, чтобы избежать конфликтов имен между стандартной библиотекой и пользовательским кодом.

person jalf    schedule 26.08.2010
comment
Очень хороший ответ! Я позволю людям голосовать некоторое время, прежде чем я решу, какой ответ принять :-) - person mtvec; 26.08.2010
comment
Обратите внимание, что зарезервированные имена зарезервированы политикой. Это не обеспечивается компилятором. Вы могли бы использовать их, если бы захотели. Как упоминает Джалф, использование этих имен сопряжено с риском того, что ваш код будет иметь конфликты имен с библиотеками, включенными в ваш компилятор (или с другим, когда кто-то другой попытается скомпилировать ваш код), поэтому очевидно, что их использование — плохая идея. - person Brian; 26.08.2010
comment
ага (думаю, я должен был упомянуть об этом, но теперь вы так хорошо с этим справились, так что вместо этого +1 вам :)) - person jalf; 26.08.2010
comment
@Tomalak: правда? Какую часть STL нельзя реализовать без магии компилятора? И могу ли я напомнить вам ваш обычный глупый аргумент, что STL — это библиотека SGI 20-летней давности? Насколько мне известно, она не изменилась. Итак, согласно вашему определению, мой ответ определенно правильный. Для остальных это немного более сомнительно, потому что остальные используют STL для ссылки на подмножество стандартной библиотеки, а в C++11 есть ряд функций стандартной библиотеки, которые требуют магии компилятора. Но есть ли совпадение между этими функциями и частью STL? Я так не думаю. - person jalf; 16.09.2011
comment
Если вы передумали и теперь готовы использовать STL для ссылки на часть стандартной библиотеки, как и остальные разработчики C++ в мире, это замечательно, но вам все равно нужно будет сказать мне, какая из частей стандартной библиотеки Стандартная библиотека C++11, требующая магии компилятора, должна рассматриваться как часть STL. Являются ли признаки типа частью STL? Я так не думаю, но вы можете чувствовать по-другому, и некоторые черты типа действительно требуют такой магии. - person jalf; 16.09.2011
comment
@Tomalak: если серьезно, я знаю, что для работы некоторых признаков типа требуется специальное вмешательство компилятора, это то, о чем вы думаете? - person jalf; 17.09.2011
comment
@jalf: Да. Я думал о стандартной библиотеке С++ 11 и немного увлёкся. Соответственно стыдно. - person Lightness Races in Orbit; 17.09.2011
comment
@Tomalak: ну, какие части stdlib? Единственный случай, о котором я могу думать, это черты типа, но могут быть и другие. Мне просто интересно, что ты имел в виду. :) - person jalf; 17.09.2011
comment
@jalf: довольно хорошо освещен в других ответах - person Lightness Races in Orbit; 17.09.2011

Как уже говорили другие, STL можно реализовать на чистом стандарте С++ 98. Что не было сказано, так это то, что разработка STL шла одновременно с разработкой механизма шаблонов C++ и в значительной степени способствовала включению определенных функций. Я считаю, что Просмотр в зависимости от аргумента (ADL, также известный как Поиск Кенига), параметры шаблона шаблона, и все аргументы шаблона по умолчанию пришли на C++, чтобы служить Степанову при разработке STL.

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

person Drew Hall    schedule 26.08.2010
comment
+1: Спасибо за урок истории! - person mtvec; 26.08.2010
comment
Если мне не изменяет память, ADL был отдельным (и даже предшествовал предложению стандартизировать STL). - person Jerry Coffin; 26.08.2010
comment
@ Джерри - я подозреваю, что ты прав. Я сейчас вдали от каких-либо соответствующих справочных материалов, поэтому я не могу подтвердить. Может быть, кто-то может нарыть полный список? - person Drew Hall; 28.08.2010

Если под STL вы подразумеваете только шаблонную часть стандартной библиотеки С++, то ее вполне возможно реализовать без какой-либо «магии». Использует ли каждая данная реализация какое-либо «волшебство» на самом деле — это другой вопрос (есть части STL, где «волшебство» может помочь, но не обязательно).

Теперь, если вы говорите обо всей стандартной библиотеке C++, то в ней действительно есть немного «волшебства». Классическим примером могут служить реализации ::operator new и ::operator delete, предоставляемые библиотекой. Мы часто называем их «перегружаемыми» на повседневном языке, тогда как формально они заменяемые. Язык C++ не предлагает пользователю такой функциональности. Пользователь не может написать заменяемую функцию.

Другим примером может служить макрос offsetof (унаследованный от стандартной библиотеки C). Хотя это обычно реализуется на «чистом C», популярная реализация на самом деле незаконна с педантичной точки зрения (вызывает неопределенное поведение). Я не видел никаких формально законных реализаций offsetof, поэтому я не уверен, возможны ли они вообще.

Другим примером могут быть (опять же унаследованные от C) макросы для работы с переменными аргументами. Очевидно, что они не могут быть реализованы на чистом C или C++.

person AnT    schedule 29.08.2010
comment
+1: позор, у этого ответа мало голосов. - person Lightness Races in Orbit; 16.09.2011
comment
'вызывает неопределенное поведение'... есть много мест, где это может быть правдой, сразу приходит на ум оператор ++. Так что это не незаконно, просто не рекомендуется. И, конечно же, вы не можете заменить оператора по умолчанию новым, вы можете заменить его функциональность для своего кода. Во всех случаях в этом ответе нет ничего «волшебного» - то есть специальных вещей, которые вы не можете использовать ни в какой форме, специальных вещей, которые доступны только разработчику компилятора и никому другому. - person gbjbaanb; 22.09.2011
comment
@gbjbaanb: Неправда. Опять же, стандартная библиотека предоставляет реализации ::operator new(size_t). Вы можете написать свою собственную реализацию ::operator new(size_t), которая возьмет на себя управление. Ничего подобного реализовать в пользовательском коде невозможно. Наличие двух внешних функций с одинаковой сигнатурой приведет к ошибке (нарушение ODR). Тот факт, что вы можете сделать это для ::operator new(size_t), является чистой магией. - person AnT; 22.09.2011
comment
Все в моем ответе относится к магии. Полагаться на неопределенное поведение во всех случаях можно только через особенности компилятора, что является своего рода магией (я не понимаю, что вы подразумеваете под своей ссылкой operator++). Фактически, компилятор GCC переключился с неопределенной реализации offsetof на явно магическую реализацию через __builtin_offsetof. - person AnT; 22.09.2011

Я почти уверен, что некоторые type_traits требуют магии компилятора, например has_trivial_constructor, has_virtual_destructor или is_pod.

person fredoverflow    schedule 26.08.2010
comment
Что ж, если это правда, я, конечно, хотел бы это знать! Кто-нибудь знает, можно ли это реализовать на чистом C++? - person mtvec; 26.08.2010
comment
ну, их нет в текущей версии стандарта. Они запланированы для включения в C++0x (и быстрый просмотр черновика не дал никакой информации о том, как они могут быть реализованы, так что вы можете быть правы, что для их реализации требуется магия компилятора — с другой стороны, их единственный тогда цель состоит в том, чтобы разоблачить эту магию компилятора, чтобы обычные разработчики могли ее использовать. Они не держат ее в себе, как это делают примеры Java @Job.) - person jalf; 26.08.2010
comment
Я быстро просмотрел tr1, в который они включены. Кажется, что стандарт определяет вещи, которые не могут быть реализованы на чистом C++, как неопределенное поведение (пожалуйста, поправьте меня, если я ошибаюсь). Например, is_pod может возвращать ложные отрицательные значения. - person mtvec; 26.08.2010
comment
Да, в C++0x будет несколько свойств типов, требующих поддержки компилятора, но я не могу вспомнить, какие именно. Им нужна поддержка компилятора, ПОТОМУ ЧТО нет возможности реализовать их на чистом C++. - person Fabio Fracassi; 26.08.2010
comment
@Job: это TR1. Версии TR1 предназначены только для библиотек, потому что они в основном заимствованы из Boost. По сути, они были не самыми близкими, которые вы могли бы получить без поддержки компилятора. C++0x делает еще один шаг вперед и предоставляет версии этих признаков типа, которые действительно работают правильно во всех случаях. И это можно сделать только с помощью какой-то неуказанной формы поддержки компилятора. - person jalf; 30.08.2010

std::initializer_list нуждается в поддержке компилятора и не может быть перереализован как другой класс (насколько я знаю), хотя я не уверен, считается ли это, поскольку он находится в С++ 0x.

person Community    schedule 02.09.2010

C++0x собирается стандартизировать некоторые де-факто "магические" свойства типов.

http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2009/n2984.htm

«Дополнительные черты типа для C++0x»

Это содержит несколько замечаний, таких как «Считается, что XXXX требует поддержки компилятора».

Смотрите также

http://gcc.gnu.org/onlinedocs/gcc-4.3.2/gcc/Type-Traits.html#Type-Traits

http://msdn.microsoft.com/en-us/library/ms177194(v=vs.80).aspx

person spraff    schedule 08.06.2011

Как правильно сказал "gbjbaanb", в реализации STL нет никакой магии. Он написан на чистом C++. Вы можете реализовать его самостоятельно, но он легко доступен в виде библиотеки, чтобы упростить вашу жизнь.

person Swapnil    schedule 26.08.2010

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

person Cătălin Pitiș    schedule 26.08.2010
comment
Но мой вопрос заключается в том, нужна ли реализация самой STL какой-либо магии от компилятора. - person mtvec; 26.08.2010
comment
@Job: нужен хороший компилятор, соответствующий стандартам. - person Chubsdad; 26.08.2010
comment
@Job: В поддержку того, что уже было сказано: Магия, требуемая от компилятора, заключается в соответствии требованиям реализации STL, что почти любой C++ компилятор и, кхм, который соответствует ему. Любая старая версия компилятора C++ не сможет работать с STL, в отличие от почти любого более нового компилятора C++. Это как Co-Evolution. - person rubber boots; 26.08.2010
comment
@chubsdad: Хороший компилятор, соответствующий стандартам, можно считать магией :) ... - person Cătălin Pitiș; 26.08.2010
comment
Любой достаточно продвинутый компилятор неотличим от магии. - person Joe D; 26.08.2010
comment
На самом деле стандарт в стандартной библиотеке шаблонов не имеет ничего общего с фактическим стандартом C++, который содержит стандартную библиотеку C++. - person Lightness Races in Orbit; 16.09.2011