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

    +152

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    typedef signed int s32;
    
    //...
    
    void SomeStruct::SomeFunc(const char* ipImageName /*, ... */ )
    {
    	// ...
    
    	s32 imageNameSize = strlen(ipImageName) * sizeof(char) + 1;
    	this->mpImageName = new char[imageNameSize];
    	strcpy(this->mpImageName, ipImageName);
    	
    	// ...
    }

    А теперь представим, что вместо char будет wchar_t... ...автор - лид-программист...

    Запостил: Kirinyale, 13 Июня 2010

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

    • вижу гавно что std::string не используется.

      на счет wchar_t .... хез. я как правило на utf-8 сижу и вайд чарами принципиально не пользуюсь. и даже на виндах... ежели дежурный не-юникод+рашн+дельфи быдлокод, то там даже wchar_t не поможет.
      Ответить
      • > вайд чарами принципиально не пользуюсь

        почему? потому что их любит гадкий майкрософт? ох уже фанатики... или потому что он места "многго" занимает? ох уже эти не вышедшие из анабиоза, рам у них 3 килоайбата до сих пор гыгы
        Ответить
        • есть utf8, он удобнее и переносимее...
          ну и как бы из контекста: игра казуальная, имена всех ресурсов известны заранее и могут быть набраны латиницей, смысла от использования вайд чара - нет...
          но с другой стороны, опять исходя из условия что игра казуальная и все ресурсы известны заранее, все файлы пакуются (идеальный случай для издателя это 1 экзешник, с всем внутри) и номеруются, смысла использовать имена файлов - нет...
          Ответить
          • > есть utf8, он удобнее и переносимее

            чем это он переносимее? абсолютно такая же портабельность. разве что есть встроенная поддержка легаси-АПИ типа libc... для использования вне libc utf8 не имеет абсолютно никаких преимуществ
            Ответить
            • проверь у себя на компиляторе sizeof(wchar_t)...
              Ответить
              • 4 под линуксом, 2 под виндой - и чё?
                Ответить
                • в utf8 всегда 1... вот как бе все преимущества...
                  Ответить
                  • А Вы не познакомите меня с магией, которая позволяет упаковать все Unicode-символы в 1 байт?
                    Ответить
                    • http://ru.wikipedia.org/wiki/UTF-8
                      Ответить
                      • И хули ты своей ссылкой тычешь?
                        ВСЕ символы 1 байтом не представить! Только ASCII подмножество, т.е. ты мудак предлагаешь транслитом писать?
                        Ответить
                        • Второй абзац прочитай, а также включи мозг и подумай, чем отличается размер символа от sizeof(char). Никто не говорил, что у UTF-8 символ всегда занимает 1 байт. Зато с ним отлично работают практически все стандартные средства, написанные для ASCII.
                          Ответить
                          • Блять ты запредельно тупой. Да похуй какой там sizeof(char) и похуй на ASCII и какой толк в этих стандартных средствах если они сосут буй на локализованных строках, даже количество знакомест не посчитают.
                            Ответить
                            • ты тупой и упоротый гест, на UTF16 и UTF32 таже хуйня
                              Ответить
                    • эта магия не нужна...
                      Ответить
          • "Казуальная" - понятие несколько шире мелких тетрисов и змеек. В данном случае финальный размер упакованного дистрибутива ожидается около 100-150 МБ; кроме того, в игре будет довольно много текстов, которые издателю ещё нужно будет локализовать своими силами (не знаю, включает ли список языков азиатские), плюс мелкие требования типа возможности свободно подменять/добавлять/удалять сплэш-скрины, выползающие при старте, в зависимости от конкретного сайта-распространителя... так что один экзешник - это уже не идеальный случай...

            Но, в принципе, на прошлом аналогичном проекте вполне нормально обошлись утф8, так что обойдёмся и здесь. Как минимум, он удобнее тем, что если некоторые данные вдруг оказались в ASCII, их не приходится постоянно конвертить туда-обратно, плюс халявные сторонние библиотеки далеко не всегда работают с wchar_t.
            Ответить
            • я знаю что такое казуальная игра...

              сплешскрины - это отдельный пак, локализация тоже...

              то есть имеем 3 пака ( данные, сплешскрины, локализация), экзешник, 1-2 DLLки... это издателю понравится больше чем 100500 мелких файлов...
              для запаковки локализаций и сплешей дайте издателю тулзу и небольшой комент как с ней работать... они не тупые, разберутся...

              ну и если быть уж совсем крутым, то все паки можно положить в ресурсы экзешника и если нет доп библиотек, то будет 1 экзешник (мы так не делали, но видели игры в которых такое есть)...
              Ответить
              • 100500 мелких файлов - это полнейший пипец производительности, и чтобы это заметить, издатель не нужен)))

                и даже не тупые временами тупят... в последний раз они почему-то не сумели нормально обернуть в свой инсталлер тулзу, перепаковывающие ресурсы из сжатого в несжатый пак... пришлось игре перепаковывать их самой на первом запуске, что естественно вылилось в проблемы при дефолтной установке в Program Files и запуске не под админом... вместо нормального решения проблемы потребовали распаковывать все полгектара прямо в All Users под виндовыми документами, итог - хозяин барин, юзеры (те, которые нашли "гостинец") недовольны, разработчикам стыдно, а шо делать)))
                Ответить
                • че за движок используете?

                  мы использовали PopCap и его PopPak. в паке ресурсы не жали, но пользовались всякими трюками для уменьшения размеров png картинок, типа квантизации...
                  Ответить
                  • движок в основном самописный, плюс куча опенсорсных сторонних либ для разных целей

                    ресурсы жались только для финала (при отладке использовались как есть, т.е. те самые 100500 файлов, зато с возможностью подменять/исправлять на лету)

                    сжимали банальным разделением PNG или TGA (в основном исходники держали в TGA - грузилось быстрее) на два JPG (картинка+маска), после чего паковали в несжатый зип
                    Ответить
                    • GPL потихоньку нарушаем? Аяяй...
                      Ответить
                      • в чём?
                        Ответить
                        • Ох не прикидывайтесь простачком. Линковка "опенсорсных сторонних либ для разных целей"....
                          Ответить
                          • У опенсорсных либ, между прочим, лицензии бывают разные. Иногда даже BSD. Конкретно их подключением и сверкой лицензий занимался не я (для этого есть лид), но насколько мне известно, ничего не нарушено. Несколько штук даже в кредитсах указано.
                            Ответить
        • Вайдчар бывает 16 и 32 бита. Разница между ними охрененная, потому что только для 32хбитного вчара выполняется правило "один вчар - одна буква". Для utf16 это не так (косяки вылезают на азиатских алфавитах). Посему виндовый 16битный вчар ничем не лучше, чем utf8 в обычных чарах.
          Ответить
          • Для большинства алфавитов wchar_t работает out of box...

            printf("%d\n", strlen("привет"));

            результат: 12

            printf("%d\n", wcslen(L"привет"));

            результат: 6

            Это несомненный плюс...
            Ответить
            • Тут нет никакого плюса, strlen и wcslen работают одинаково хорошо. И strcat тоже. А вот взятие подстроки начинает порождать проблемы, ибо число букв (а не объём памяти) приходится считать хитрым способом, а иначе появляются всякие ромбики с вопросиками и прочие факапы.
              Ответить
              • > Тут нет никакого плюса, strlen и wcslen работают одинаково хорошо

                одинаково хорошо если рассматривать строку просто как кусок памяти.

                а если как некий набор буков, то wchar_t для некитайцев просто прекрасен.
                Ответить
                • Чем прекрасен? Что ты такого делаешь, что разница с utf8 есть, а граблей нет?
                  Ответить
                  • я же уже сказал. если я допустим срал на китайцев и кобминейшон марки, то вчар у меня будет работать как надо: один чар = юникодная буква. Следственно и субстринги, поиск и т.п. проще и быстрее намного. В утф8 надо хуйнёй какой-то с префиксом _mb/mb- изворачиваться как я понял, ибо стандартные средства типа стрлена, стркцпу работают с байтами, а не с логическими чарами... или скажи чо как делать? вот хочу я измерить строку "хуй" не в байтах а в чарах. Чё делать? как я понял mblen юзает текущую локаль, но не утф8, т.е. нет гарантии, что будет верно. Надо ебаться с setlocal'ами. Пиздато, особенно под винду!
                    Или вот хочу иметь логический чар 'Ж'. В утф8 не могу такого сделать. А в вайдчарах будет L'Ж'.
                    Ответить
                    • давай закончим героическое высасывание проблем из пальца и попытки грамотно их решить прикручивая то что в данном случае вообще не нужно...
                      а на счет азиатов ты зря... если судить по играм, рыное японии второй по величине после сша, причем рынок сша постоянно сокращается, а китая растет...
                      Ответить
                      • да китайцы это не люди, похуй мне на них
                        Ответить
                        • >китайцы, похуй мне на них
                          Они это тебе припомнят, когда станут хозяивами мира.
                          Ответить
                    • к стати, если у тебя в проекте часто встречается L'Ж', можешь постить его на главную...
                      Ответить
                      • почему? кириллический чар не имеет право на существование?
                        Ответить
                        • я тут недавно с cfdev ругался (он теперь ника своего стесняется) по поводу магических цифр, ща начну с тобой по поводу магических символов...
                          по своему опыту скажу, везде где в данный момент нужен 1 символ (особенно с кодом больше 127) через месяц будет нужна строка...
                          ну и как бы локализация намекает на полное отсутствие строк в нац алфавитах в коде, поэтому в 99% случаев монопенисуально сколько байт занимает 1 символ (1% это функция DrawString)
                          Ответить
                          • > по своему опыту скажу, везде где в данный момент нужен 1 символ (особенно с кодом больше 127) через месяц будет нужна строка...

                            потому что опыт у тебя с убогим утф8
                            Ответить
                            • ты поймешь насколько убог UTF16 как только выйдешь за рамки UCS2... еще нехило доставляет проблема LE&BE...
                              Ответить
                              • поживём увидим

                                под виндой это лучшее средство по крайней мере
                                Ответить
                                • это лучшее средство только под виндой!
                                  Ответить
                                  • а почему ява не использует утф8? как прокомментируете?

                                    дотнет а следовательно моно - тоже...
                                    qt вроде тоже не утф8
                                    Ответить
                                    • я когда-то писал тулзу для паковки текста из UCS2 в UTF8, чтоб потом читать из игры на яве...
                                      нутри себя строки в яве и дотнете могут быть чем угодно, никто никогда не узнает как они устроены, так как язык это обернет в свои абстракции...
                                      даже для С++ есть классы которые позволяют работать с utf8 строками, как с utf16/utf32.
                                      c QT не работал, незнаю, спорить не буду...
                                      Ответить
                                      • > нутри себя строки в яве и дотнете могут быть чем угодно, никто никогда не узнает как они устроены

                                        В дотнете чётко прописано, что строка должна быть в utf16 (http://msdn.microsoft.com/en-us/library/system.string.aspx):

                                        "Each Unicode character in a string is defined by a Unicode scalar value, also called a Unicode code point or the ordinal (numeric) value of the Unicode character. Each code point is encoded using UTF-16 encoding, and the numeric value of each element of the encoding is represented by a Char object. "

                                        насчёт явы не знаю, но большинство реализаций, которые я знаю, используют внутренне utf16.

                                        вот нашёл (http://java.sun.com/javase/technologies/core/basic/intl/faq.jsp):

                                        "The Java programming language is based on the Unicode character set, and several libraries implement the Unicode standard. The primitive data type char in the Java programming language is an unsigned 16-bit integer that can represent a Unicode code point in the range U+0000 to U+FFFF, or the code units of UTF-16. The various types and classes in the Java platform that represent character sequences - char[], implementations of java.lang.CharSequence (such as the String class), and implementations of java.text.CharacterIterator - are UTF-16 sequences."

                                        В дотнете это особеннно важно, потому что можно сделать строку pinned и передать в нативный код сразу указатель на чары без маршаллинга:

                                        fixed(char* cs = &str) { }

                                        без значния внутренней кодировки мы бы так делать не могли
                                        Ответить
                                      • Вы на С++\cli не програмировали. В дотнете специально делали внутреннюю реализацию наиболее совместимую с Си++ строками(wchar_t).
                                        Ответить
                                    • UTF8 скоро захватит мир.
                                      Ответить
                              • >LE&BE
                                Ыыы. Кстати, это вообще прикол, да. :)
                                Ответить
          • > азница между ними охрененная, потому что только для 32хбитного вчара выполняется правило "один вчар - одна буква"

            да нифига, если юзать combination marks, то на одну букву может быть и два 32битных вчара... везде одни и те же траблы
            Ответить
            • так если везде одинаковые проблемы то почему не utf8?
              Ответить
              • Согласен. В утф8 эти проблемы легче обнаружить на этапе разработки. А, например, в утф16 придёться отлаживать китайскую версию. программы. :D
                Ответить
          • > Вайдчар бывает 16 и 32 бита

            если в GCC указать -fshort-wchar, то вайдчары и под линуксом будут 2 байта. правда, стандартные функции типа wcslen/wcscpy не будут работать...
            Ответить
            • std::wstring будет работать.
              Ответить
              • точно? а то я почитал интернеты, с++ так убого запутан, что напр. в некоторых компилерах шаблоны прекомпиленные, т.е. если сделать вчар 2байтным, то в прекомпиленных\ шаблонах всё равно он будет treat'иться как 4байтный

                с быдлос++ ни в чём нельзя быть уверенным
                Ответить
                • катаюсь по полу... прекомпиленные шаблоны должны появиться в С++0х...
                  Ответить
                  • по полу катаешься, пена изо рта? санитары димедрол забыли вколоть?
                    Ответить
                  • у тебя эпилепсия? не знаю как в твоём любимом майкрософт визуал-анал сиплюсплюс, но в интернете пишут, что некоторые платформы "прекомпилируют" (может быть, это интринзик) некоторые распространённые стандартные шаблоны (компилятор какбэ не ожидает, что вчар может быть не четыре байта под линем). мопед не мой.
                    Ответить
                    • сначала разберись что такое С++ а потом отнекивайся от мопеда...
                      в некоторых случаях в реализации строк на С++ не включают шаблонные варианты функций работы со строками, а используют str* (mb_str*) и wcs* функции для char и wchar_t, соответственно... если мы делаем wchar_t 2 байтным, то все функции wcs* отваливаются... об этой проблеме уже писали (хотя для этого случая есть воркараунды)... по моему этой непонятки должно хватить с головой чтоб перестать пользоваться wchar_t...
                      Ответить
                      • по моему этой непонятки должно хватить с головой чтоб перестать пользоваться с++...
                        Ответить
                      • Из всего что ты наплёл я правильно понял, что std::wstring может испольозвать wcs*? Тогда в чём профит юзать std::wstring? Чтобы чувствовать себя неибацца ООПоёбом?

                        > по моему этой непонятки должно хватить с головой чтоб перестать пользоваться wchar_t...

                        это не понятка не вчара, а конкретно gcc
                        Ответить
                        • > Тогда в чём профит юзать std::wstring?
                          тут вопрос стоит зачем нужен wchar_t? если есть причины по которым он нужен, то использовать std::wstring или нет - дело автора (причина выбора такие же как и при выборе std::string).
                          А профит в том, что работа со строками становится намного проще, уже не нужно думать о всяких str*, mb_str*, wcs* об утечках памяти, о буферах достаточной длинны и тд, то есть все что ненавидят в С++ шарписты, явисты, пехапешники, и др... да, за удобство придется расплачиваться производительностью, поэтому если она нужна придется велосипедировать, благо С++ никого не принуждает, за что его и любят...
                          Ответить
                          • >С++ никого не принуждает, за что его и любят...

                            Лол) Если на него(на С++) кто-то садится, то тот его изнасилует пополной.
                            Ответить
                          • > А профит в том, что работа со строками становится намного проще, уже не нужно думать о всяких str*, mb_str*, wcs* об утечках памяти

                            это да, только что делать, если я не пишу на с++
                            Ответить
                            • >что делать, если я не пишу на с++
                              VB в твоём распоряжении обезьянка.
                              Ответить
                              • Спасибо, я предпочитаю C.
                                Ответить
                                • обычно это звучит как
                                  > спасибо, я не осилил С++
                                  Ответить
                                  • C каких пор язык для индусских обезьянок стал сложен для асиливания? Сам не смог асилить?
                                    Ответить
                                    • к вашему сожалению, индусских обезьянок осиливших яву, шарп, похапе и питон, на 2 порядка больше чем индусов осиливших С++...
                                      на этом сайте людей осиливших С++ не больше десятка... то что уэбкилл коментит темы по С++ не значит, что он его осилил...
                                      Ответить
                                      • чем тебе ява шарп и питон не нравится?
                                        Ответить
                                        • они мне нравятся, я даже ими пользуюсь... мне не нравятся их "фанаты", которые постоянно пытаются найти недостатки С++ и доказать, что С++ медленнее, постоянно придумывая какие-то неадекватные тесты...
                                          Ответить
                                          • Ты чем-то упоролся видимо... Если ты не в теме, до появления всяких жаб индусы как раз на С++ кодили, не переоценивай это говно. И только С++ники дрочат свои микроскопические тесты, поэтому и озлоблены на весь мир.
                                            Ответить
                                            • это ты не в теме... тут буквально недавно ссылка пробегала, на которую надрачивали все "не фанаты С++" с криками, что в С++ тормозит хип...
                                              Ответить
                                          • Все идет по спирале.

                                            В 1994г выпустили книгу по VB. Там было сказано, что раньше писать под windows было просто нереально сложно, потому что надо было писать тысячи строк кода на сях, и вообще не понятно как люди умудрялись писать программы.


                                            В 2004м вышла книга про C#, где было сказано что без автоматической сборки мусора писать физически нереально, и до появления .NETа писать программы могли только доктора пяти наук
                                            Ответить
                                  • > обычно это звучит как
                                    >> спасибо, я не осилил С++

                                    Нет, это звучит так: "шутку понял, но всё равно не смешно".
                                    Ответить
                            • >что делать, если я не пишу на с++
                              Подрочить.
                              Ответить
                            • >>это да, только что делать, если я не пишу на с++
                              Да ничего. Продолжай делать говносайты за $ 15 на PHP, макак ты несчастный
                              Ответить
                              • Спасибо, я предпочитаю C.
                                Ответить
                                • Си Си си   си       си ....

                                  Соси!
                                  Ответить
                                • ну на сях ты лабы сдаешь, а когда закончишь школу -- чем будешь зарабатывать?
                                  Ответить
                                  • попкой конечно. сиплюсплюс ведь, пидары и так далее...
                                    Ответить
                            • >что делать, если я не пишу на с++
                              Мой полы.
                              Ответить
    • ну про std::string я вообще молчу... этому человеку религия не позволяет пользоваться 90% возможностей С++... но суметь написать выделение памяти через new, по форме явно расчитанное на malloc, и при этом неправильное даже для него - это сильно...
      Ответить
      • Вообще-то std::string не панацея, в некоторых случаях его нельзя использовать.
        Например, если приложение на MSVC использует один рантайм, подключает библиотеку которая использует другой рантайм, могут возникнуть проблемы из-за разных реализаций. И обычно, stl'ские классы убирают из интерфейсных частей, заменяя их char'ами и т.п..
        Данный говнокод выдран из контекста, и сказать плохо то что нет std::string, или хорошо, однозначно нельзя.
        Ответить
        • Контекст - казуальный геймдев, платформа - винда, с потенциальным портированием на айфон. Код не в интерфейсной части.
          Ответить
          • Казуалка для гламурных педиков, новое слово в игрострое.
            Ответить
            • почти... для американских тёток за тридцать
              Ответить
            • когда ты и твои однокласники начнете покупать игры, а не качать на торентах, тогда игр для педиков будут делать меньше... сейчас игры делают для тех, кто платит, естественно для них и упрощается геймплей...
              Ответить
              • покупать парашу? увольте-с, милейший...
                Ответить
              • Раньше здоровье в играх не востанавливалось автоматически. А сейчас...(((
                Ответить
    • просто поменять char на wchar_t не получится, так как не темплейт, для wchar_t нужно будет использовать wcslen...
      возможно ваш лид сталкивался с платформами на которых char больше 1 байта...
      Ответить
      • "на которых char больше 1 байта"
        Наверное имелось ввиду, больше 8ми бит?
        Ответить
        • а если даже больше 8ми бит, то какая разница, если всё исчисляется в приденённом коде всё равно в итотге в "условных единицах", т.е. в байтах? да хоть мильон
          Ответить
          • в одном байте, не обязательно 8 бит. А один char - 1 байт.
            Ответить
    • ну хорошо, допустим, размер char 2 байта... чего мы добиваемся, выделяя под копию 10-символьной строки 21 символ (т.е. 42 байта)? или, если заменить new на malloc, 21 байт (т.е. 10 с половиной символов)?
      Ответить
      • "допустим, размер char 2 байта"
        RTFM, в данном случае стандарт C++.
        Ответить
        • стандарт C++ не указывает количество байт в char
          Ответить
          • Тогда ещё раз RTFM.
            Ответить
            • http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2005/n1905.pdf

              страница, строка?
              Ответить
              • стр 89:
                "The sizeof operator yields the number of bytes in the object representation of its operand."
                ...
                "sizeof(char), sizeof(signed char) and sizeof(unsigned char) are 1."

                для общего развития, стр 5:
                "The fundamental storage unit in the C++ memory model is the byte. A byte is at least large enough to contain any
                member of the basic execution character set and is composed of a contiguous sequence of bits, the number of which
                is implementation-defined
                ."
                Ответить
                • Ок. Хотя на странице 62 есть ещё такое вот обтекаемое замечание:

                  Objects declared as characters (char) shall be large enough to store any member of the implementation’s basic character
                  set.

                  Впрочем, меньшим говнокодом сабж от всего этого не становится.
                  Ответить
                  • "member of the implementation’s basic character set."
                    слово basic, имхо убирает всю обтекаемость.

                    "Впрочем, меньшим говнокодом сабж от всего этого не становится."
                    Я вообще-то ещё не говорил о своей оценке сабажакода. Я указал на ваше говновысказывание, которое может подтолкнуть к высеранию говнокода вами, и тех кто прочёл это ваше высказывание.
                    Ответить
                    • Спасибо за формальную поправку, но я своим говновысказыванием имел в виду не столько сам факт возможности или невозможности того, что sizeof(char) равен чему-то, кроме единицы, сколько последствия этого, если бы это было возможным, т.к. человек, написавший подобное, запросто мог бы повторить что-нибудь похожее и с любым другим типом, включая объектный...

                      Перефразирую: "вернёмся к примеру с wchar_t и заменим для компилируемости strlen/strcpy на соответствующие аналоги".
                      Ответить
                      • Я соглашусь с Webkill'ом, больше похоже на невнимательность.. и ведь действительно шаблонов-то нет.
                        Человек который будет менять на wchar_t, возьмётся и за strlen, и скорей всего заметит каку.
                        А вообще wchar_t планируется?
                        Ответить
                        • Нашёл то же самое в ещё нескольких местах. Либо бездумный копипейст, либо невнимательность хроническая, либо просто "для красоты". В memset домножение (бесполезное, с учётом стандарта) на sizeof(char) - сплошь и рядом. Я бы, кстати, тогда уже писал бы что-то вроде sizeof(*ipImageName) или sizeof(ipImageName[0]) - от этого было бы куда больше толку в случае внезапной смены типа.

                          wchar_t пока что вроде не планируется.
                          Ответить
                  • да чё непонятно-то.

                    байт это семантически единица.
                    байт может реализовываться любым количеством битов.

                    в байте может быть 16 бит, но это всё равно будет ОДИН байт.

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

      вообще судя по всему, учитывая что он рядом пишет sizeof(char) и 1, это похоже на ошибку по невнимательности
      Ответить

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