1. C++ / Говнокод #25298

    0

    1. 1
    2. 2
    Почему весь С++ засран явными неймспейсами std:: ?
    Если из-за коллизий, то почему с этим нету проблем в C#, Java?

    Запостил: Lorip1971, 10 Января 2019

    Комментарии (263) RSS

    • В "Java" всё засрано java., com., org.
      А в "C#" всё засрано System. и Microsoft.
      Ответить
    • Или вопрос в том, почему «using namespace std» считается дурным тоном?

      1. В старых версиях "C++" не было поддержки неймспейсов.
      2. "STL" не сразу стала стандартом. Раньше были другие «стандартные» библиотеки, у каждого компилятора своя.

      Вот это всё стало стандартом только во второй половине 1990-х, а учитывая, что тогда в порядке вещей было использовать старые версии кокококонпеляторов и библиотек, процесс внедрения "STL" растянулся на долгие годы.

      Чтобы подчеркнуть принадлежность именно к "STL", явно пишут префикс std:: (а то вдруг проект использует аналогичные имена из других библиотек).

      "Java" и "C#" разрабатывались сразу с поддержкой неймспейсов и сразу со стандартными библиотеками, поэтому в них всё по-другому (хотя нужно заметить, что для "Java" существуют и «нестандартные» библиотеки).
      Ответить
      • показать все, что скрытоvanished
        Ответить
      • >> Или вопрос в том, почему «using namespace std» считается дурным тоном?
        да, именно это я имел ввиду.
        все понял. спасибо.
        Ответить
      • Я бы ещё добавил, что результат «using namespace std» в принципе предсказать невозможно: мало того, что любые сторонние заголовочные файлы тянут непредсказуемое количество стандартных заголовков, так ещё и сами стандартные хедеры причудливым образом включают в себя своих товарищей. Так, к примеру, в VS2017 из <functional> мы получим std::list и std::tuple (вместе с кучей других имён), а <array> тащит за собой <algorithm>. Поэтому «#include <vector>\n using namespace std;» принесёт в нашу область видимости не std::vector, а огромную кучу непредсказуемого дерьма с непредсказуемыми именами.
        Ответить
        • P.S. Только что подсчитал: после включения одного <vector>, в std:: оказалось около 1300 имён (включая начинающиеся с «_»).
          Ответить
          • показать все, что скрытоvanished
            Ответить
            • Ога.
              For comparison, here are line counts
              (after preprocessing, removing empty lines) of various
              STL headers in the same compiler:
              
              * <vector>: 20354
              * <string>: 26355
              * <unordered_map>: 24291
              * <map>: 21144
              * <algorithm>: 18578
              * vector+string+unordered_map+algorithm: 35957
              * <cstdlib> 1800; just <stdlib.h> itself: 1184. C was small and neat!


              http://aras-p.info/blog/2018/01/12/Minimizing-windows.h/
              Ответить
              • показать все, что скрытоvanished
                Ответить
                • Precompiled header все стерпит...
                  Ответить
                  • Кстати, а как в precompiled header'ах реализована работа с шаблонами? Все специализации складываются в один объектный файл или шо?
                    Ответить
                    • он же не объектный, это скорее индексированный AST

                      но так-то есть возможность вынести специализацию 100 этажного шаблона в .cpp файл из 2 строчек, чтобы компилятор там поднапрягся, инстанциировал всё что надо, сохранил в .o, и при трансляции всего остального уже не сходил с ума, а просто при линковке туда уже обратился - я так делал когда-то, когда кокомпилятор студии просто валился с внутренней ошибкой из-за превышения потребления оперативной памяти
                      Ответить
                      • > превышения оперативной памяти
                        Бустовая метушня?
                        Ответить
                        • давно у жены в вузе было что-то типа курсача по теории компиляторов, и мы решили, что все охуеют, а некоторые даже ебанутся, если принести работу не на yacc как все, а на спирите
                          тем более, что грамматика там очень близко к исходному заданию визуально описывалась, было красиво

                          с тех пор больше не доводилось сталкиваться, что компилятору не хватает 12ГБ рам, но и на крестах я уже давно не писец правда
                          Ответить
                          • > на спирите
                            Я никогда конечно не осуждаю то, что происходит между двумя consenting adults, но такое...
                            Ответить
                  • показать все, что скрытоvanished
                    Ответить
                    • Зачем? Всякая бустятина с ним гораздо бодрее компилится.
                      Ответить
                      • показать все, что скрытоvanished
                        Ответить
                        • Или вообще напитоне.
                          Ответить
                        • ...Для этого можно скачать нашу небольшую (32 Кб) утилиту SimpleFix 1.8. Убедитесь, что в системе установлен Microsoft .NET Framework 5.0 Service pack 1.1. (скачать можно с официального сайта microsoft.com)

                          SimpleFix версии 2.0 не требует установки .NET Framework. Инструкция по установке Python 3.0.5 находится на сайте python.org. (обратите внимание, на 64-битных системах при прописывании переменной PATH нужно заменить Program Files на Program Files x86) Внимание! Перед установкой Python3 нужно удалить предыдущую версию Python2.
                          Ответить
                          • показать все, что скрытоvanished
                            Ответить
                            • живенько вспоминается, что толстый клиент vmware vsphere (который сейчас уже забанен в угоду веб-уи) на 10 винде требовал дотнета 3.5, пока у всех стоял 4+, и надо было лезть куда-то в компоненты доустанавливать
                              Ответить
                              • Именно поэтому я за программы, которые можно записать в загрузочный сектор флешки и не думать о зависимостях.
                                Ответить
                              • показать все, что скрытоvanished
                                Ответить
                                • Ну, утилитку можно и статически слинковать. Или три dll-ки рядом кинуть (и манифест не забыть, а то "Приложение некорректно настроено" чочо такое мне релиз выкатывать у клиента не запускается а я ваще не пони чо это значит77???)

                                  По крайней мере, в MSVС так, но и в GCC, наверное, дожна быть статически линкуемая версия crt...
                                  Ответить
                          • Несколько лет назад увидел на одном сайте программу, которую автор позиционировал как очень полезную утилиту для военных, потому что она может использоваться в целеуказании. В инструкции по применению рекомендовалось перед установкой программы установить VB Runtime, а если вдруг программа перестанет работать, рекомендовалось ввести команды:
                            regsvr32 COMCTL32.OCX
                            regsvr32 COMDLG32.OCX
                            regsvr32 DBGRID32.OCX
                            regsvr32 DBLIST32.OCX
                            regsvr32 MSCOMCTL.OCX
                            regsvr32 MSDATGRD.OCX
                            regsvr32 TABCTL32.OCX
                            И ещё несколько подобных команд.

                            Уже представил себе, как командир в окопе под обстрелом пытается починить рантайм Вижул-Барсика.

                            https://i.pinimg.com/originals/fc/df/9d/fcdf9d9489314ec2162fb0eae2cea75a.jpg

                            К слову, нужную функцию (перевод прямоугольных декартовых координат в полярные и обратно) инженерные микрокалькуляторы выполняют одной кнопкой.
                            Ответить
                • #define WIN32_LEAN_AND_MEAN             // Exclude rarely-used stuff from Windows headers
                  #include <windows.h>


                  Еще когда-то использовал что-то типа:
                  typedef stuct CONTEXT *pCONTEXT; // Чтобы не ругалось
                  #include <windefs.h>
                  Ответить
                  • NOMINMAX еще надо.
                    Ответить
                    • Не поможет: http://lolengine.net/blog/2011/3/4/fuck-you-microsoft-near-far-macros
                      Ответить
                      • А вдруг ты в 2019-м году решил по-быстрому портировать на современную систему код, написанный для «Windows 3.1», а удалять директиву «far» тебе лень? Да-да, 100500 вызовов переписал в соответствии с современным API, а «far» не удалил?

                        А вдруг следующая версия «Windows» снова будет поддерживать сегментную модель памяти, тогда слово «far» снова пригодится?
                        Ответить
                      • >> Turns out that Microsoft has #defined rad1 0x0420 and rad2 0x0421.

                        >> Well, Microsoft's rpcndr.h (whatever that is) has "#define small char".

                        А потом люди не верят, когда им говорят, что макросня –— зло.
                        Ответить
                        • Именно поэтому я никогда не инклужу windows.h в хедерах. Там еще #define interface struct где-то был.
                          Ответить
                          • Если не путаю, то в кокококом-то кокококонпеляторе были интерфейсы (в борландовском?), так что #define interface struct всё ломало.
                            Ответить
                            • Всё, нашёл. Ключевое слово «interface» было в «Delphi» и в странном языке «IDL», предназначенном для некоего «MIDL compiler», а также в «ODL» (внешне такая же хрень).
                              Ответить
                              • Начал читать мокросохтовскую тугоментацию по IDL. Нашёл забавный абзац: «The array can also contain two values separated by an ellipsis that represent the lower and upper bounds of the array, as in [lower...upper]. Microsoft RPC requires a lower bound of zero. The MIDL compiler does not recognize constructs that specify nonzero lower bounds.»

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

                                Давайте включать в документацию всё, что мы не собираемся поддерживать. Например, объявим ключевое слово для грабежа корованов, но напишем, что наш кококонпелятор грабить корованы не сможет. Вот здорово будет!
                                Ответить
                              • > Ключевое слово «interface» было в «Delphi»

                                Оно вроде во всех паскалях есть –— разделы interface и implementation в модулях.
                                Ответить
                                • Паскаль любишь?
                                  Ответить
                                • Да, но в Delphi, начиная с кокококой-то версии его переюзали. Теперь оно используется в двух местах:
                                  1. В разделе модуля.
                                  2. В ООП как хитрая разновидность класса с обсрактными методами, да ещё и с поддержкой COM.
                                  Ответить
                                  • показать все, что скрытоvanished
                                    Ответить
                                    • Вирт бы проклял, Хейлсберг— от души посмеялся, Томаш Гриштар—смущенно улыбнулся, а Каганович заставил бы партбилет сдать.
                                      Ответить
                                      • Интерфейсы - интерфейсами, но нет ни одного серьезного языка, в котором тип "строка" не был бы реализован через жопу:

                                        * строковые операции крайне медленные
                                        * много несовместимых между собой типов, привязанных к кодировке (в RAD Studio ввели универсальный тип UnicodeString, не базирующийся на BStr, памятью управляет само приложение, но среда при этом - ужасное говно)

                                        Вывод: строк, этого уродливого наследия Visual Basic, не должно быть в принципе; ручками выделил память - ручками освободил, как в C. В пасцальных языках в качестве "строк" нужно явно использовать Array of char. Меньше ёбли с подсчётом ссылок, меньше ёбли с реаллоками памяти==прирост скорости.
                                        Ответить
                                        • показать все, что скрытоvanished
                                          Ответить
                                          • Борландовские ресурсы подгружаются один раз при запуске - не понимаю, что тебя так напугало.
                                            Речь сейчас не о скорости запуска, а о скорости исполнения бинаря.
                                            Ответить
                                          • >> Там блять ФОРМА из ресурсов распаковывается (!)

                                            Никто не заставляет использовать "VCL".
                                            Ответить
                                        • показать все, что скрытоvanished
                                          Ответить
                                          • В тех же делфях их дохуя: WideString, AnsiString, ShortString.

                                            Например, склейка, присваивание и любые другие, где строка модифицируется.
                                            Строки иммутабельны, т.е. при изменении данных всегда происходит изменение значения счётчика ссылок, а также неявное выделение/освобождение памяти (причём - по каждому чиху). Как бы ни старался опытный программист оптимизировать свой код (минимум кода, асмовставки, не более 3 параметров у методов) строки всё равно окажутся самым дорогим удовольствием.
                                            Ответить
                                            • показать все, что скрытоЭто Вы, доктор? Вернулись?
                                              Ответить
                                            • показать все, что скрытоvanished
                                              Ответить
                                              • Я кажется русским языком сказал - "все серьезные языки", т.е. нативные, работающие без VM.
                                                Ответить
                                                • Жабба и сисярп нисирьозные изыки?
                                                  Ответить
                                                • @@В .NET или JVM строки живут в куче и присваивание там это присваивание указателя (да и в питоне примерно так же), очень дешево

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

                                                    В BP строки были мутабельными, но там этого добились путём ограничения размера строки. Если ты помнишь, string[N] сразу выделял память под N символов (если размер не указан, подразумевалось 255) и превысить этот размер было нельзя.

                                                    Скопированный из Си тип PChar допускал изменение на месте, но опять же только в том случае, если ты не пытаешься изменить размер.
                                                    Ответить
                                                    • Фактически, я учил делфи ради написания утилиты для чистки флешек - задачу эту я с успехом выполнил, хотя сорцы проебал. Теперь мне глубоко похуй, что там да как. Я отошёл от кодинга, ибо кроме сколиоза ничего не заработал. Фрилансом я не маюсь. Даже вон оператором не могу устроиться, хотя есть диплом (купил в местной шаражечке за семь косарей).
                                                      Ответить
                                                    • @Если ты пытаешься изменить размер строки, то без выделения нового блока памяти никуда.

                                                      Я хз есть ли функция StrRealloc, но если вызвать просто ReallocMem, то предыдущее содержимое буфера не затирается. Я хз, баг это или фича.

                                                      Оказалось, что поведение ReallocMem напрямую зависит от менеджера памяти. Как правило, предыдущее содержимое буфера сохраняется.
                                                      Ответить
                                                      • Фича. В сишке реаллок тоже сохраняет контент.
                                                        Ответить
                                                        • А есть у перфомансофагов функция, которая работает как realloc, только специально не копирует значения?

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

                                                            В «Windows» есть функции «LocalReAlloc» и «HeapReAlloc», которые можно попросить ничего не выделять и ничего не копировать (т. е. вернуть ошибку), если выделенный блок нельзя оставить на старом месте. Их также можно попросить не обнулять новый кусок памяти при расширении.
                                                            Ответить
                                                • Вообще есть проект "gcj" –— кококонпелятор "Java" в нативный кококод. И другие извращения:
                                                  http://govnokod.ru/22504

                                                  Но это всё несерьёзно, потому что у них в библиотеке воссоздаётся некое подобие VM.

                                                  P.S. Язык «Vala» кто-нибудь изучал?
                                                  Ответить
                                                  • Excelsior JET еще есть
                                                    https://www.youtube.com/watch?v=G9Oj3e1XCRg
                                                    Ответить
                                            • >> Строки иммутабельны

                                              Именно поэтому я за "ShortString" (это тот string, который был в "BP 7.0"), потому что у него нет никаких ссылок.
                                              Ответить
                                              • Пожалуй, самый тупой тип. По сути, это голый указатель на array[0...255] of char
                                                Ответить
                                                • Это был даже не указатель, а сам массив, ибо под него не надо было выделять место в куче.
                                                  Ответить
    • показать все, что скрытоvanished
      Ответить
    • Пишут для того, чтобы было понятно, откуда взялись функции или типы, и где их потом искать.

      Дурным тоном считается не «using namespace std», а любой «using namespace» в принципе, т. к. он засирает текущий скоп непредсказуемым числом символов и делает программу менее читабельной.

      Когда ты видишь в незнакомом коде std::ios_base, ты сразу понимаешь, что ios_base — это не специфичный для проекта класс для iOS, а что-то из стандартной библиотеки, что можно найти на cppreference.

      Более того, поскольку число импортируемых символов не предсказуемо, код может перестать компилироваться, если в импортируемый целиком неймспейс в будущем добавят символов, т.к. это может создать неоднозначность.

      В жабе во многих гайдлайнах импорты со звёздочкой тоже считаются дурным тоном.
      Ответить
      • При этом надо понимать, что в теории нет ничего зазорного в том, чтобы написать

        using std::string;

        в .cc файле (НЕ В ХЕДЕРЕ!). Это не мешает читабельности и не создаёт потенциальных проблем.

        Для сторонних библиотек я всё же предпочитаю выписывать неймспейс явно. Если неймспейс длиннее 5 букв, я обычно создаю алиасы (ТОЖЕ НЕ В ХЕДЕРЕ), например

        namespace fs = boost::filesystem;
        Ответить
      • > Более того, поскольку число импортируемых символов не предсказуемо, код может перестать компилироваться, если в импортируемый целиком неймспейс в будущем добавят символов, т.к. это может создать неоднозначность.

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

        Вообще, эта блядская пидоросня с неймспейсами - ее еще хрен реализуешь по стандарту, и куча всяких багов с этим говном есть:

        https://gcc.gnu.org/bugzilla/show_bug.cgi?id=51577 например этот баг живет аж с 2011 года, чего-то там в неймспейсе находит, но не должно находить.
        https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87208 и вот это еще, этот относительно недавний, но тоже косяк с этим перегрузочным бредом и неймспейсами

        придумали еще кучу каких-то припизданутых правил чтоб какое-то там перегруженное говно в говнонеймспейсе искать https://en.cppreference.com/w/cpp/language/adl

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

          Если совпадают ещё и символы в неймспейсах, то нельзя. Из-за нарушения ODR, линкер только одну функцию с заданным именем возьмёт. Это не сильно зависит от языка, так нельзя делать ни в сишке, ни в хаскеле.

          Собери себе два бинарника с разными версиями либ, так все делают.
          Ответить
          • > Если совпадают ещё и символы в неймспейсах, то нельзя. Из-за нарушения ODR, линкер только одну функцию с заданным именем возьмёт. Это не сильно зависит от языка, так нельзя делать ни в сишке, ни в хаскеле.

            Вообще-то это решаемая проблема. Ну т.е. это можно было бы решить на уровне языка (приделать говнорасширения какие-нибудь), но ни в Си, ни в крестах это на уровне языка не решается.

            Т.е. допустим у нас есть некий гипотетическй язык, типа особая улучшенная сишка, и файлы main.c и library_v1_0.c library_v1_1.c library_v_1_0.h library_v_1_1.h

            Пусть library_v1_0.c и library_v1_1.c предоставляет нам некую функцию do_shit(). Предположим, что мы хотим из main.c и оттуда и оттуда эту хрень вызывать.

            Ну что ж, это можно решить, если процедуру линковки описывать каким-то хитрым образом в самом исходнике, и делать декорирование имен.
            #include <library_v_1_0.h> __attribute(mangle, "v_1_0_")
            #pragma comment( lib, "library_v1_0.o", mangle, "v_1_0_" )
            
            #include <library_v_1_1.h> __attribute(mangle, "v_1_1_")
            #pragma comment( lib, "library_v1_1.o", mangle, "v_1_1_" )
            
            int main(void)
            {
              v_1_0_do_shit();
              v_1_1_do_shit();
              return EXIT_SUCCESS;
            }


            Ах да, еще можно тупо менять символы в объектниках, например через
            https://www.agner.org/optimize/objconv-instructions.pdf#[{"num"%3A22%2C"gen"%3A0}%2C{"name"%3A"XYZ"}%2C87%2C734%2C0]

            и
            https://sourceware.org/binutils/docs/binutils/objcopy.html

            --redefine-sym old=new

            Change the name of a symbol old, to new. This can be useful when one is trying link two things together for which you have no source, and there are name collisions.


            --redefine-syms=filename

            Apply --redefine-sym to each symbol pair "old new" listed in the file filename. filename is simply a flat file, with one symbol pair per line. Line comments may be introduced by the hash character. This option may be given more than once.
            Ответить
          • Кстати, как вся эта крестопитушня с манглингами, перегрузками и неймспейсами сочетается с dlopen() / dlsym() ?
            Ответить
            • https://stackoverflow.com/a/497158 - дерьмище какое-то
              Ответить
              • Виртуальные методы более-менее совместимы у разных конпеляторов. И у них нет имён, а значит и проблем с манглингом.

                В принципе, взаимодействие крестов с COM на такой хуйне и замутили.
                Ответить
              • З.Ы. На самом деле, это один из лучших вариантов для взаимодействия с крестами.

                Всё остальное сводится либо к чисто сишному интерфейсу либо к ёбле с манглингом, который даже с разными версиями одного конпелятора не всегда стыкуется.
                Ответить
                • > З.Ы. На самом деле, это один из лучших вариантов для взаимодействия с крестами.

                  Но это ж говно.
                  нахер надо где-то делать
                  
                  extern "C" MyClass* create_object()
                  {
                    return new MyClass;
                  }
                  
                  extern "C" void destroy_object( MyClass* object )
                  {
                    delete object;
                  }
                  
                  и потом где-то
                  
                  create = (MyClass* (*)())dlsym(handle, "create_object");
                  destroy = (void (*)(MyClass*))dlsym(handle, "destroy_object");

                  ?

                  Почему эту херню нельзя как-нибудь автоматизировать, без всей этой хуйни? Ну пусть даже каким-нибудь блядогенератором, который нагенерит эту парашу с dlsym-ами и экстернами, если крестометушня такое делать не позволяет.
                  Ответить
                  • Да там и без генераторов не всё так ужасно.

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

                    А нижняя херня заворачивается в няшную RAII'шную обёртку.

                    Т.е. будет как-то так:
                    // на стороне либы
                    DEFINE_ROOT_OBJECT(MyClass);
                    
                    // на стороне клиента
                    Library<MyClass> lib("foo.so");
                    lib.GetRootObject()->КакаяТоХуйня();
                    Ответить
            • показать все, что скрытоvanished
              Ответить
              • И если у тебя есть в C++ куча перегруженных функций типа:
                int shit(int a, int b);
                float shit(float a, float b);
                double shit(double a, double b);

                которые надо уметь вызывать, то ты это говно будешь вилкой чистить руками заворачивать с extern "C" в некое говно вида
                int shit_int_int_int(int a, int b);
                float shit_float_float_float(float a, float b);
                double shit_double_double_double(double a, double b);

                да ?

                Или для этого уже написали какие-то гомоиконы кодогенерации?
                Ответить
                • Какие-то у тебя слишком простые функции, которые тривиально заворачиваются.
                  Ответить
                • Представь, какая ёбля тебя ожидает при вызове функции, принимающей std::string.
                  Ответить
                • Т.е. мало переименовать функции. Тебе ещё придётся вилкой вычистить все лишние типы. На extern "c" границе должны остаться только POD и указатели. И я не уверен, что генератор без твоей помощи с этим справится...

                  З.Ы. В биндингах к Qt можешь посмотреть как выглядит настоящий хардкор - использование неадаптированных крестолиб из другого языка. Но у Qt ABI стабильное в отличие от всякой стдушни, могло быть и хуже.
                  Ответить
    • Лучшие неймспеси в "Forth" (словари) —– коллизий никаких нет, переопределять можно любое слово, старое слово никуда не денется, просто новое будет найдено первее, можно удалять слова из словаря с FORGET или MARKER (точнее вернутся к состоянию которое было до какого-то слова), в SP-FORTH я видал как делали временные словари в куче, ещё можно как угодно менять словари в порядке поиска и текущий конпелируемый словарь. Можно даже вообще все словари из порядка поиска убрать и форт-система будет понимать только числа, а всё остальное будет ошибкой:
      \ set-order принимает на стеке id словарей последний .. первый и их количество
      0 set-order
      1 2 3 \ числа обработаются без ошибкав, а этот комент —– нет, потому что слово "\" не будет найдено
      Ответить
      • Но если я отключу все словари, то как вернуть их обратно? set-order же проебётся вместе с одним из них.
        Ответить
        • Никак, система станет неюзабельна (разве что кормить ей числа на проверку ;)), это просто пример, но зато можно поставить какие-нибудь свои словари и убрать стандартный, и вуаля, свой ЯП готов.
          Ответить
    • https://youtu.be/qTTsZbfg7Ug?t=208
      Ответить
    • > Почему весь С++ засран явными неймспейсами std:: ?

      А чем его надо засирать? Говном? Ну это можно:
      #include <iostream>
      
      #define shit std
      
      int main()
      {
          shit::cout << "Hello, world!" << shit::endl;
      }


      Перегрузка неймспейса через препроцессор
      Ответить
      • namespace shit = std;
        Ответить
        • Это плохая перегрузка. Через препроцессор можно сразу перегрузить "std::cout <<" и "<< std::endl"

          #include <iostream>
          
          #define shit std::cout <<
          #define turd << std::endl
          
          int main()
          {
              shit "Hello, world!" turd;
          }
          Ответить
      • Пойдём дальше:
        #include <iostream>
        
        #define shit std
        #define shIt int
        #define Shit main
        #define sHit () {
        #define SHit }
        #define sHIt cout
        #define sHiT <<
        #define shIT endl
        #define ShiT ;
        #define ShIT ::
        #define SHIT "Hello, world!"
        
        shIt Shit sHit
            shit ShIT sHIt sHiT SHIT sHiT shit ShIT shIT ShiT
        SHit

        https://ideone.com/0SKmJB
        Ответить
    • C++ гвно. За 20 лет никакого прогресса в синтаксисе. Попытка заткнуть все возможные дыры привело в тому что такой краказялбы в миру трудно найти. Хотя с# прикрасно компилиться во все нетивные платформы и точно также можно поддерживать все навороты unsafe кода как и в c++
      Ответить
      • > За 20 лет никакого прогресса в синтаксисе

        ЛОЛОЛОЛЛО
        Ответить
      • показать все, что скрытоvanished
        Ответить
        • 1) нет киворда но зато есть имютабле обьекты - а это одно и тоже
          2) легко. вызывай .clone() :)
          3) а структуры которые не в свойствах класа думаешь где хранятся? или думаешь они по поинтеру передаются :)
          4) есть немного но думаю скоро и тут придумают как обойти
          Ответить
      • Скоро поехавшие программисты на крестах будут писать «auto auto(auto) { auto; }», а всё остальное время — загорать на Мальдивах и посмеиваться над отсталыми сишарперами, продолжающими писать бойлерплейт.
        Ответить
        • void do_zaebis() = auto;
          Ответить
        • Осталось только написать шаблон шаблона шаблонов для передачи кобенаций данных для обсчёта в мировой вычислительный континуум указателей на указатели.
          Ответить
        • показать все, что скрытоvanished
          Ответить
          • да генериков достаточно на все
            Ответить
            • Можно на генериках вычислить факториал в компайл-тайме? А AES сделать? А дифференциальные уравнения считать? Нет? Сосут, сосут эти ваши «генерики»!
              Ответить
            • показать все, что скрытоvanished
              Ответить
              • иди читай разницу между джавой и шарпом. и как устроины дженерики.
                это в жабе дженерик на обжект заменяется и потому нельзя перегрузку делать.
                в сишарпе же дженерик в рантайме имет конкретный тип, который, коль надо, через рефлексию можно узнать (привет dependency injection). и перегрузки тоже работают с дженериками.

                я бы сказал не 80%, а в 98% случаев нахуй никому не уперлось факториалы через темплейты считать. кроме как const int pituh = 60*60*24*365 и конкатенации строк вообще не понимаю, коим хуем тебе еще что-то надо считать в компайл тайме? кому нахуй вообще уперлость факториалы считать, ты когд их-то блять считал последний раз? так что не пизди.
                Ответить
                • показать все, что скрытоvanished
                  Ответить
                  • в шапре нету понятия примитива и обертки как в жабе. в шарпе есть велью и референс тайпы. шарповые дженерики могут и в то и в друге безо всяких кажурок. и будет в дженерике именно то, что ты там написал, ничего не будет боксится/анбоксится.

                    на счет перегрузок, ты мне ща задвигаешь какую-то дичь. какием хуем твой кусок код соотносится с этой фразой?
                    >> С генериком у тебя не будет работать перегрузка по типу потому что класс-то один.
                    вот жабе, из-за недоженериков, как раз такое не канает:
                    public static void Spam(List<String> s){}
                    public static void Spam(List<StringBuilder> s){}

                    т.к. после конпеляции все будет List, т.е.:
                    public static void Spam(List s){}
                    public static void Spam(List s){}

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

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

                                Указатель всегда одинаковый, и так как знание о типе есть в рантайме у .NET то можно сделать указатель типа object, и просто явно его проверять и кастить под капотом.

                                Зачем плодить кучу классов?

                                С валуе обжектами ситуация другая: можно конечно их боксить как в джаве, но это будет супер неоптимально потому что потребует еще места в куче и указатель.

                                Потому .NET пошли на хитрость.

                                Джава так не умеет, и традицийно отсосала хуй, и потому List<Integer> сильно больше и тяжелее чем int[], а в .NET они примерно сравнимы.

                                В С++ _всегда_ инстанциируются новые классы. Иногда это реально не нужно: например зачем тебе 20 классов с указателем? И тогда люди идут на хитрость через partial template specialization (Частичная специализация)

                                Ну то-есть как всегда: в С++ можно сделать как хочешь, C# за тебя автоматом делает хорошо, а Java за тебя автоматом делает так себе)
                                Ответить
                          • Какой смысл создавать разные типы для классов в .NET, если там всё равно референс под капотом?
                            Ответить
            • А так можно?
              template <typename T> class FatherOf {};
              class Pitux : public FatherOf<Pitux> {};
              Ответить
              • показать все, что скрытоvanished
                Ответить
                • Где-то такое не работало. Кажется, в C#.

                  В C++ работает, не сарказм.

                  Даже есть примеры, когда автор программы упарывается настолько, что это пригождается:
                  https://www.boost.org/doc/libs/1_51_0/libs/spirit/classic/example/fundamental/full_calc.cpp
                  ////////////////////////////////////////////////////////////////////////////
                  //
                  //  Our calculator grammar
                  //
                  ////////////////////////////////////////////////////////////////////////////
                  struct calculator : public grammar<calculator>
                  {
                  Ответить
                  • показать все, что скрытоvanished
                    Ответить
                  • работает в шарпе такое на ура. без этого половина дженериков бы нахуй не была нужна.
                    IComparable например, имеено так и работает. и им обмазы все стандартные типы чтобы мамкины кодеры могли делать естественную сортировку, не указывая функцию-компаратор, а-ля Array.Sort(pituhi).
                    Ответить
                  • вообще, предел дженериков шарпа очень хорошо нам демонстрирует один поехавший, который обмазавшись то ли хаскелем, то ли ф-шарпом, нахуярил вот такой багор (смотреть где-то в районе монад):
                    https://github.com/louthy/language-ext
                    Ответить
        • Забавно, но на ГК есть два непересекающихся класса обитателей — те, кто реально пишут на крестах, и те, кто считает, что они не нужны.
          Ответить
          • Думал над этим высказыванием 13 часов, но так ничего и не понял. Переведи!
            Ответить
            • Есть те, кто пишет на крестах. И те, кто считает, что пишущие на крестах нинужны.
              Ответить
              • Ничего не понимаю. А какова ситуация с другими языками?
                Ответить
                • Есть те, кто пишет на «1С». И те, кто считает, что пишущие на «1С» не нужны.

                  Есть те, кто пишет на „Паскале“. И те, кто считает, что пишущие на „Паскале“ не нужны.

                  Есть те, кто пишет на 『Ruby』. И те, кто считает, что пишущие на 『Ruby』 не нужны.

                  Есть те, кто пишет на “Lua”. И те, кто считает, что пишущие на “Lua” не нужны.
                  Ответить
              • Роман же всё довольно однозначно написал.
                Есть те, кто пишет на крестах. И те, кто считает, что <их собственная жизнь тлен, и> они не нужны.
                Непересекающиеся биомассы.
                Ответить
            • показать все, что скрытоvanished
              Ответить
            • перевел на js:

              "Забавно, но на ГК есть два непересекающихся класса обитателей — те, кто реально пишут на крестах, и те, кто считает, что они не нужны."
              Ответить
          • > Забавно, но на ГК есть два непересекающихся класса обитателей — те, кто реально пишут на крестах, и те, кто считает, что они не нужны.

            Не, ну я вот например могу что-то на крестах написать вполне, на шаблонах могу рекурсивного говна понаписывать.

            Или под "писать на крестах" подразумевается что-то большее, типа профессионально на крестах что-то пилить за зарплату? Ну а с чего б нелюбителю крестов этим заниматься? Логично, что подобные люди будут избегать подобной работы.

            Забавно другое - чем больше я узнаю кресты, тем меньше мне кресты нравятся. В самом начале я эти кресты воспринимал как просто такое улучшение, типа "круто, тут еще какой-то свой препроцессор, который назвали шаблонами", "круто, тут еще по ссылке передавать можно", "круто, какие-то классы-хуяссы", а когда вникаешь поглубже во все это дерьмище, то хочется побыстрее съебать обратно в сишку. Особенно если почитать какого-нибудь кода с этими классами, шаблонами и перегрузками
            Ответить
          • показать все, что скрытоvanished
            Ответить
          • Вообще, на ГК приходят отдыхать от своей работы. Вероятно, те, кто пишет на пердольных языках и так на работе настрадались, потому на ГК говорят на другие темы.

            Я бы сказал, пересечение множеств тех, кто реально пишет на языке и тех, кто считает, что он не нужен или крут, пропорционально выразительности языка и обратно пропорционально пердольности и порогу вхождения (с округлением до целых)
            Ответить
          • Не только на ГК. Такую картину я наблюдаю много где.

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

              Мы вынуждены принимать кучу утверждений на веру т.к. проверять всё снуля долго и дорого. И это абузят все кому не лень.
              Ответить
              • Верно

                Вот например ты наверное думаешь, что земля имеет форму шара, чуть сплюснутого у полюсов, да?

                А почему ты так думаешь? Разве ты когда-нибудь видел землю из космоса?
                Ответить
        • Ну как, уже загорают?
          Ответить
    • показать все, что скрытоvanished
      Ответить

    Добавить комментарий