>>1871276 Единственный нормальный язык. Когда-то думал, что все начинают изучать кодинг с C/C++, а затем открыл для себя двач.хк/пр и увидел вопросы "а почему функция print() в питоне такая сложная, помогите(((".
Крестовики, никак не могу решить стоит ли активно юзать исключения для эррор хэндлинга. В каких ситуациях, кроме ебейшего хуйлоуда и эмбедщины, эксепшены лучше не юзать, а дрочить ошибочки как в чистой Сишке?
>>1871393 std::span, заебался таскать велосипед designated initializers наконец-то в стандарте template parameter list для лямбд вместо ебли с using T = std::decay_t<decltype(zalupa)>
>>1871393 std::format офк. Как блять в здравом уме вообще могла придти идея использования стримов которые мало того, что писать не удобно так еще и по производительности проигрывают сишным printf.
>>1871544 В плюсах почти все проигрывает Сишке по производительности. Без углубления в дебри, Сишный компиль банально генерит меньше машинного кода, ибо сам язык гораздо проще и примитивнее плюсов.
Под эксепшены должна быть заточена вся архитектура модуля\софтины. В последнее время я вот стараюсь их использовать и рекомендую всем использовать в учебных\самопальных проектах.
Но если у тебя в проде уже есть положняк уровня "никаких эксепшенов", как, допустим, в том же гугле - то увы.
>>1871669 да кто тебе это сказал? Щас во всех компиляторах почти Zero Cost эксепшены, когда они не кидаются. Причем этот оверхед отсуствует только если у тебя эксепшены полностью отключены, либо каждая функция помечена как на ноэксепт.
Сам процесс КИДАНИЯ\ЛОВЛИ конечно медленнее, но другое дело, что исключение - это именно исключение, и кидаться должны очень редко. Это серьезных холиварный вопрос про архитектуру приложения, а вот срач за перф тут - правда хуйня.
>>1871671 Звучит как оправдание говнокода, который подпирают эксепшенами как костылями чтоб игнорить ошибки. > кидаться должны очень редко Никому они не должны ничего. И в любой либе ты можешь получить тонну этого говна за воротник.
>>1871394 Примерно всегда. Во-первых, они пиздецки усложняют флоу кода, во-вторых, чаще всего просто весь кидающий эксепшены код заворачивают в трай-кетч, и ложат хуй пока работает (а потом кто-то, возможно и ты, будешь ебстись, разгребая стектрейсы и логи, чтобы узнать что кто-то просто хуй клал), в-третьих — они тормозят.
Короче, ошибки-значения лучше во всём, но в плюсы ADT не завезли, поэтому чтобы таким заниматься придётся писать кучу бройлерплейта, так что увы и ах.
>>1871680 >Звучит как оправдание говнокода Пчел, то есть, когда все вокруг — сидят на всякой нагенеренной мышкой xml-like залупе для проектов/интерфейса/итд которую невозможно не замерджить ни поправить без ебли; — юзают жирные форматы для передачи данных когда есть куча готовых бинарных форматов (которые зачастую даже удобнее если платформы больше 1-й); — юзают говно мамонта когда уже есть сотня альтернатив, причём половина проверена в бою; — согласны с политической ситуацией кекус; — итд. тебя такие костыли не смущают, а эксепшены — прям пиздец? Это типичная хуйня для сокрытия проблемы, поэтому и используется.
>>1871682 >они тормозят Экспешены по-моему тормозят только если сотая вложенная функция кидает исключение и стэк анвайндится на много кадров назад, чтобы попасть в подходящий кеч. Условно говоря (хоть и ситуация оторвана от реальности), если throw и catch находятся в одном и том же стэковом кадре, то рантайм замедления вообще почти не будет (ибо в таком случае не раскручивается стэк).
Гугл запрещает своим плюсокодерам юзать эксепшены, но в гугле плюсы только в адовом хуйлоуде (и в хроме), поэтому там это оправдано. Но везде ли надо высасывать максмум производительности, кладя хуй на читаемость и поддеживаемость кода?
>>1871671 Вот этого поддвачну. Стоит просто отделить код, который должен работать быстро, и код, в котором могут возникать исключительные ситуации. Первый проектировать как работающий всегда корректно и полностью обмазать noexcept-ом и ассертами упало? давай корректные данные или иди нахуй, из второго аккуратно подливать/забирать данные для первого, всякую валидацию делать тут же.
>>1871689 >Но везде ли надо высасывать максмум производительности, кладя хуй на читаемость и поддеживаемость кода? >>1871682 >Во-первых, они пиздецки усложняют флоу кода, во-вторых, чаще всего просто весь кидающий эксепшены код заворачивают в трай-кетч, и ложат хуй пока работает (а потом кто-то, возможно и ты, будешь ебстись, разгребая стектрейсы и логи, чтобы узнать что кто-то просто хуй клал) ТРЕД НЕ ЧИТАЙ @ СРАЗУ ОТВЕЧАЙ
>>1871708 Ну ты-то можешь не писать, я просто объяснил, что это такая же конъюнктура как и в других областях как программирования так и жизни в целом — такое говно существует и ты будешь его есть потому что диды ели.
>>1871727 Ну тогда можешь начать писать бройлерплейт из обвязок ко всему остальному миру, не юзающему исключения (и в большинстве случае плюсы вообще, лол), а потом такие же только уже для связи твоего софта с внешним миром (и прокидывать коды из эксепшенов, кекс).
>>1871922 Что такое "краш потока"? Если в потоке выброшено исключение, то все деструкторы вызовутся, если в потоке будет сегфолт или повреждение памяти, то все, приехали, тут уже ничего не поможет.
>>1871960 Рефлексия зло. Понаклепали сисярповых либ на рефлексии, а потом их на любую платформу с ahead-of-time компиляцией не заюзать (например на айфоны)
>>1872006 Можно только через макросы, но там пиздец костыли приходится юзать. Вот сейчас я использую самописную хуйню через макросы. Для моих структур она работает, но если нужно сериализовать структуру из библиотеки какой-нибудь, то все соси хуй. Нужна поддержка именно на уровне языка.
>>1871394 без исключений в языке не обойтись тк конструкторы и перегруженые операторы не имеют другого способа вернуть ошибку об этом рассказывал страуструп в "дизайне и эволюции" еще 30 лет назад по похожей причине, кстати, и появилась перегрузка - так как требовалось конструировать объекты классов разными способами, значит нужно несколько конструкторов, значит нужна перегрузка, значит нужен общий механизм перегрузки, а значит нужно запиливать перегрузку и функций-членов и свободных функций когда страуструп делал первоначальный дизайн языка он исходил из логики что для решения частной проблемы нужен общий механизм, иначе это будет "костыль"
>>1872301 > иначе это будет "костыль" Так это и есть костыль. Если у тебя в конструкторе кидается исключение, то деструктор не вызывается и ты сосёшь немытый хуй. Сами конструкторы говнище. А у нормальных пацанов ошибки через Optional работают.
>>1872301 >что для решения частной проблемы нужен общий механизм Это главная ошибка в софтверной разработке чего либо. Убивал бы нахуй. Если null был ошибкой на миллиард долларов, то вот эта ебучая овердженерализация всего на свете - это ошибка на все деньги ёбаного мирового банка.
>>1872346 Имхо в данном конкретном случае это не плохо, иначе ты бы охуел от количества фич, которые существуют только чтобы использоваться в единственном месте. В чем вообще доёбка? Типа надо было сделать что перегрузка есть - но только для конструкторов, исключения кидать можно - но только из операторов?
>>1872346 На то время альтернативой было: errno; возвращать через ссылочный параметр; возвращать в результате 0 или true. Так что да, общий механизм это охуенно. А то что не распознали его недостатки, так это как доебываться почему сразу не изобрели какую нибудь Джаву еще в 50-х - тут только на опыте можно узнать.
>>1872325 >Если у тебя в конструкторе кидается исключение, то деструктор не вызывается и ты сосёшь немытый хуй. как правильно обрабатывать исключения в конструкторах, написано в каждом учебнике по с++..
>>1872374 к примеру, 10е правило в книжке майерса "эффективное использование с++, 35 новых способов.." или в книжке саттера "сложные задачи на с++", задача 2.13..
>>1872346 не соглашусь, в контексте дизайна языка как раз следует использовать одно из главных правил проектирования инженерных систем - если есть частная проблема, то для хорошего решения возможно потребуется общее решение
>>1872301 >тк конструкторы и перегруженые операторы не имеют другого способа вернуть ошибку Очень обидно кстати. Писал несколько либ с перегруженными операторами, которые потом работали в ядре и не только, приходилось стараться, ведь -fno-exceptions
Аноны, выручайте. Вместо лампового h файла у меня откралась какая-то хита. Вместо кода вот такое: [Project] FileName=KF.h Name=KF_Project Type=1 Ver=2 ObjFiles= ...
>>1872413 Ууу, ну всё тебе пизда. Если прямо сейчас выдернешь комп из розетки, может ещё отделаешься заменой диска. А лучше беги от него на безопасное расстояние. Бля, я конечно всякой херни в жизни насмотрелся, но такую жесть первый раз вижу..
>>1872402 Когда уже запилят компилятор с ИИ-оптимизатором машинного кода? Чтоб наконец смогли писать как на питоне, а ИИ генерировал оптимизированный код.
>>1872325 >у нормальных пацанов ошибки через Optional работают И как потом обрабатывать ошибку которая произошла? Например в винапи там хуева туча разных кодов. По идее нужно что-то типо optional только вместо bool флага (есть значение или нет) нужно хранить код ошибки.
>>1872683 Так всякие наркоманы обдолбятся сойлента и пилят ИИ для написания кода из естественных языков, но почему-то не делают более очевидную вещь - высокоуровневый код в ассемблер.
>>1872598 Зависит от компилятора. Теоретически, препроцессор создаёт новый файл после препроцессинга, компилятор делает из него файл с кодом на языке ассемблера, ассемблер создаст из него объектный файл, а линкер сделает из объектного файла бинарник. Но в разных компиляторах это всё может быть объединено в одну стадию так, что на вход у тебя исходник, а на выходе сразу бинарник. Как сделано конкретно в G++ - хуй знает. Возможно, он реально создаёт каждый раз новый файл, но ты их не видишь, потому что они в какой-нибудь папке temp.
>>1872924 Хочешь сказать, что одна маленькая goto с комментарием для ясности или специальная конструкция throw try catch хуже нагроможденного вездесущего if? И как ты планирешь с его помощью впринципе разделять ошибку и обработку ошибки?
>>1872942 Даже так лучше, чем ебучий забор из скобок посреди кода. Лучше функцию в if оборачивать, чем разрывать код. Это же настоящий goto, прыгающий по коду к catch.
>>1872946 try { func(88888, 993) }; catch(int) {...} вместо func(88888, 993); сильно напрягает? И throw try catch всего-навсего прыгает при ошибке в определенное место , так что это не ухудшает читаемости.
>>1872383 ну, примеры того, как проектировать подобные вещи есть в стандартной библиотеке оператор квадратных скобок генерирует исключение, но есть функция at которая возвращает ошибку при выходе из диапазона оператор new имеет перегрузку с флагом nothrow_t.. при проектировании своих классов можно поступить примерно так же ткак сделано во втором случае можно сделать и с конструкторами, те предусмотреть два способа конструирования класса - с генерацией исключения в конструкторах в случае неудачи, либо с вариантом двухэтапной инициализации (с функцией init или с флагом sucsess, на выбор) те можно сделать универсальное решение при желании, достоинство с++ в том что он предлагает средства на уровне языка для того и для другого
>>1872960 Причём немного ебли только при ловле, сам проброс охуенно удобен. Точно лучше, чем перегружать сигнатуры функций возвратом ошибок, которые никто потом не проверяет.
>>1872976 с другой стороны, конструирование объектов классов прямыми вызовами конструкторов это прошлый век, ибо давно уже придуманы разнообразные фабрики классов, паттернов создания штук пять навскидку любой кодер на с++ вспомнит, причем с реализацией как в динамике, так и на статике.. причем они включают в себя и то что нужно делать в случае неудачи создания объекта..
>>1872960 Надо как в Zig хотя бы делать: const number = parseU64(str, 10) catch |err| pizda(err); Или аналог крестов: if (parseU64(str, 10)) |number| { doSomethingWithNumber(number); } else |err| switch (err) { error.Overflow => { ... }, error.InvalidChar => unreachable, } Для человеческого освобождения памяти при ошибке: const foo = try tryToAllocateFoo(); errdefer deallocateFoo(foo); > прыгает при ошибке в определенное место Так и goto в определённое место прыгает. Ещё как ухудшает, когда у тебя внутри функции скачет куда-то.
>>1872976 >оператор new имеет перегрузку с флагом nothrow_t.. Это-то да, а вот из T& operator+=(const T& rhs); ошибку возвращать некуда. Кроме эксепшена.
Да и для new пришлось свой nothrow tag делать, так как stdlib не было. Особенно кекнул с #if STDLIB #include <new> else define your own placement new
>>1872986 в книжке gof, к примеру, это третья глава "порождающие паттерны" а у александеску аж три главы отведено на то как сделать подобное, но на статике
>>1872976 >>1872986 Ну так-то даже без крупных фабрик можно использовать named constructor, который будет возвращать хоть expected, хоть optional, хоть кидать эксепшен
>>1872997 для операторов кстати есть еще третий способ сигнализировать об ошибке - а именно все тот же флаг sucsess, который выставляется в удачу или неудачу при ошибке
>>1872988 Не понимаю чё там сверху, но объективно, в отличии от goto всегда понятно откуда (из соседней функции) и куда (в соседний catch) передается ход программы, ясно почему (ошибка) ясно что делать (в catch), ясно какая ошибка (выбирается определенный catch) и после работы с ошибкой, программа продолжает идти с логичного места как и должна была, будь всё хорошо.
>>1873014 > откуда > почему А если ошибка прилетает из глубины? Возвращаемое значение обязывает сразу обработать ошибку, а catch может из глубины кишок поймать говно.
>>1873039 Допустим у нас есть Много функций вложенных друг в друга, у каждой из них есть throw, и соответственно вызываем мы каждую функцию подобным образом: try { func(88888, 993) }; catch(int) {...} Тогда говёна с глубин не придут, а выйдя из своей функции с throw сразу попадут в try и catch соответсвенно, где можно написать какая функция ошиблась и как то обработать ошибку. Если нужно подняться на определенный уровень, например на самый высокий к вызову, для ошибки достаточно написать уникальный вызов хз как называется и тогда она развернет всё до самого верха и активирует нужны catch где всё будет понятно.
>>1872960 В реальности такого не будет, у тебя будет портянка кода по который ты будешь скроллить вверх вниз пытаясь найти к какому же траю относится катч.
>>1873053 > мы каждую Ключевое во всём этом. Это должен кодер гарантировать, но ты никогда не узнаешь наверняка что там, не прочитав исходник или стэктрейс. Речь была про читаемость и вот где вся проблема. Ты предлагаешь верить в то что оно как надо сделано, звучит как полная хуйня. Опять же, возвращаясь в Zig, там язык гарантирует что подобной хуйни не будет и выполнение кода не уйдёт хуй знает куда, хуй знает откуда - ты делаешь обработку ошибки сразу и явно передаёшь её куда надо.
>>1873129 Чё??? Если нельзя узнать что в функции, то можно организовать проверку в вызывающем коде. Про zig я вообще не понимаю причём он тут и я с ним вообще не знаком.
>>1873139 > можно организовать проверку в вызывающем коде Предлагаешь писать проверки просто чтоб наверняка? Оборачивать всё этими кишками как в сишарпе, просто для уверенности? Надо на этапе написания кода знать что не будет эксепшенов из глубины функции. А то этот goto может вообще из зависимости либы прыгнуть в мой код, а я как должен узнать заранее что такое может произойти? Я ведь надеюсь что эксепшен прилетит из вызываемой функции, а по факту это просто вангования.
>>1873349 >BOOST_HANA_DEFINE_STRUCT не поддерживает инициализацию сразу же в объявлении поля. >Boost.PFR ну а это вообще хуйня, можно пройтись только по значениям полей, а имена полей оно не определяет (т.е. в json ты не конвертируешь с этим).
>>1873459 >дружественной функцией шаблонному классу? Это чтобы перегруженный оператор видел внутренние поля объекта. >std::move заворачивать в return? Ты, наверное, хотел сказать return заворачивать в std::move? Затем, чтобы временно созданный объект не гоняли туда-сюда, а оптимизатор сразу записал результат в исходный объект.
>>1873459 >Перегрузка оператора является дружественной функцией шаблонному классу? Hidden friend idiom. tl;dr нужна, чтобы не засорялось пространство имён. >Зачем std::move заворачивать в return? Хз, по идее это только мешает NRVO.
>>1873526 > Затем, чтобы временно созданный объект не гоняли туда-сюда, а оптимизатор сразу записал результат в исходный объект. Хотели как лучше, отстрелили себе ногу по самое ебало. В c++17 такая хуйня гарантирует отсутствие copy elision, следовательно можно сделать вывод, что автор книги - долбаёб.
>>1873541 Тут не работает НРВО, ты какую-то произвольную ебалу в ретюрн написал а не имя переменной. Всё правильно обёрнуто. *= возвращает T&, значит это lvalue выражение, делаем мув, получаем рвалью.
>>1873605 Во всех более менее современных языках ошибка возвращается в виде тупла [err, result] = call_func(...) Тут просто предлагается использовать для возврата err уже существующий канал - там где данные по исключению. Получаем плюсы от обоих подходов (не забудешь обработать err)
>>1871463 Вот жеж мудак на пикче. Высрал свою книгу по шаблонам, другой мудак впечатлился и высрал на них относительно объёмную прогу-сервис на стандарте с++03. А я потом с этого кода охуевал. При том, что решать поставленную задачу шаблонами не было никакой необходимости, банальная прикладная приложуха.
>>1873885 Почти одно и то же. Второй пример выполняется после первого, если в наличии оба. Позволяет иметь "дефолтное" значение, а потом другим конструкторам иметь "более приоритетные дефолтные" значения.
>>1873887 В первом примере работает копирующая инициализация, то есть в строке int m_value = 5, сначала создается интовый объект 5, а потом его значение копируется в m_value, или в случае с инициализацией членами класса компилятор сразу даст m_value значение 5 без порождения лишних объектов? Просто я где-то видел, что лучше всего использовать только списки инициализации, и если ответ на мой вопрос в абзаце выше будет "да", то тогда для меня очевидна выгода списков инициализации -- нет порождения лишних сущностей, напрямую инициализирует объект. Если же ответ, будет "нет", то, выходит, нет разницы, каким способом инициализировать члены класса?
>>1873887 >Второй пример выполняется после первого, если в наличии оба. Тогда почему следующий код не печатает сообщение "Hello" дважды? class Hello { public: Hello() { cout << "Hello" << endl; } };
Перекатился на Dev c++ 5.11 потом что visual studio выгнала, а тут простейшие вещи не работают. Что не так? Красная строчка вот это подсвечивает 10 27 D:xxxxxxxxx\main.cpp [Error] no match for 'operator>>' (operand types are 'std::basic_istream<char>::__istream_type {aka std::basic_istream<char>}' and '<unresolved overloaded function type>')
>>1874300 Это значит, что ты не указал, что такое oper и что ты вообще хочешь. Но если предположить, что ты студент, то oper у тебя это char, то ты должен вот эти твои плюсики и звёздочки обернуть в одинарные кавычки. К тому же ты не сравниваешь этот твой oper со знаком деления, что всегда вернёт тру вроде.
Бля что ж оно не выходит из if? Если оставить одно условие, допустим oper != "+" то всё работает, а если два и больше то тут хоть || хоть or соединяй просто постоянно по циклу гоняет.
template<class In, class T> Как зовутся эти разные названия в темплейтах? И есть ли вообще какая-нибудь разница между ними? Если да то как их все нагуглить?
>>1874694 Параметры шаблона Как угодно. Руководствуются здравым смыслом и семантикой. Посмотри как в стандартной либе (но там ещё с подчёркивания начинают, так в стандарте положено) и в бусте называют
>>1874753 Думаю надо будет создать класс, принимающий биты и выдающий инт, но это какой-то оверинжиниринг. Если у тебя константа то что не просто литерал? 0b11011
>>1874753 Строго говоря - никак, потому что фолды работают с операторами. Тебе придется как-то переопределять оператор и возможно заворачивать булеаны во вспомогательный класс.
Почитал об std::variant. Возник вопросы к практикующим: Первый - а как часто вы использовали подобные вещи? Второй - а на сколько реально надо закапываться в stl?
>>1874764 Я этот инт потом передаю в шейдер и там по маске смотрю какой бит установлен. Для отладочного рисования делаю. >>1874756 Хотел его, но там нельзя элемент получить по индексу, а писать list.begin() + i как-то не очень. >>1874766 Функции достаточно.
>>1874896 >а как часто вы использовали подобные вещи Мне вариант ещё тогда бустовый было удобно делать, когда один формат парсил, и там строки, числа и другие структуры были. >на сколько реально надо закапываться в stl Условные lower_bound и make_heap тебя спросят максимум на собеседовании, но основные операции (erase, remove(_if), find(_if), transform, for_each, sort, copy(_if) и другие) надо уметь хотя бы хорошо читать. Но STL в основном логично построен, похожие операции возвращают и принимают похожие вещи, так что это не слишком сложно. ЕМНИП вот хороший доклад: https://www.youtube.com/watch?v=2olsGf6JIkU
Вот как бы нечто такое выглядело в коде? Можно, конечно, передавать массив строк, а затем пусть функция-обработчик события преобразовывает строки в нужный аргумент.
Посоветуйте что почитать/посмотреть на тему хороших практик и оптимизации быстродействия готовых программ. Что-нибудь вроде того, что происходит здесь на 28:00: https://www.youtube.com/watch?v=zBkNBP00wJE
>>1871682 Ошибки-значения лучше, когда они идиоматичны для языка и переупаковка их нормально оптимизируется компилятором. Если в плюсах везде использовать std::variant<Norm, Huevo> и пробрасывать, получишь миллион копирований/перемещений.
>>1871682 Ошибки-значения лучше, когда они идиоматичны для языка и переупаковка их нормально оптимизируется компилятором. Если в плюсах везде использовать std::variant<Norm, Huevo> и пробрасывать, получишь миллион копирований/перемещений.
Пните в нужное направление, у меня не получается вывести отдельно кириллические буквы из строки в g++, вывожу через консоль. Пробовал wchar_t, char, const char.
>>1875394 1 это int. Выражение при вычислении приводится к самом у широкому типу, знаковый считаеться более широким чем беззнаковый (хотя в них может быть одиинаковое количество чисел). (a - 1) - преобразуется обратно в беззнаковый при присваивании, (b-1) выводится как есть, тоесть как знаковое.
>>1875461 Потому что у тебя логика странная. Ты почему-то из "для компилятора есть разница" делаешь вывод "получается разное в дизасме", а я этого не говорил.
>>1875472 Я это к чему спрашиваю, это как с inline. По стандарту написано что все методы описанные внутри своего класса должны быть inline, но все равно серьезные дядьки из гугла/милкософта/etc пишут руками как на пикче (этого я тоже не понимаю)
Такой же вопрос избыточности или нет возник и с constexpr. Тем более что я тут погуглил, и оказалось что есть моменты, где без constexpr const просто не будет компилироваться (указатели на constexpr)
Xто-то стандарт С++ полон таких мелких нюансов, о которых многие забывают/не знают.
Вот про inline - четко и ясно написано. И все равно люди пишут >>1875481 Не, я бы понял если бы речь была про forceinline. Но тут inline
А я например с помощью main вычисляю говноучителей в ютубе - кто не знает, эта единственная функция (точнее все семейство из почти десятка вариантов) в которой разрешено не писать return
>>1875554 >Пиши const constexpr const __attribute__((const)), не ошибёшься. Я вот не понимаю, нахера в С++ вводят кучу необязательных классификаторов? По типу, ну может быть оно будет таким, как написали... А может и не будет
>>1875617 >Пчел... 13 лет назад был С++ 03. В котором уже было про inline методы внутри классов. Так что не аргумент. И это не настолько давно - я в те годы как раз загорелся идеей стать программистом и трогал всякие делфи (и даже видел такое чудо как делфи.нет)
>>1871183 (OP) Что происходит при объявлении указателя на класс Node<T> head как поля класса List? При создании объекта класса List c параметром Node<T> head, вызывается конструктор Node, а затем в класс List передается указатель на только созданный объект Node?
>>1875560 И? Я здесь >>1875496 как раз и сказал, что они уже инлайн. Это всё ещё к тому же вопросу, зачем писать inline там, где он уже и так имеется ввиду.
То что тут >>1875485 чувак криво мысли формулирует — не моя проблема.
>>1875545 Ты тупой какой-то. Может, у них практика такая, чтоб можно было потом эту функцию легко перенести из class scope в namespace scope в хедере. Тогда inline не придётся дописывать. А может автор кода аутист. Зачем нам разгадывать его мотивы? Ты это как авторитетный кусок кода принёс, потому что он в гугловской кодовой базе? Охуеть просто. А может ему нравится быть explicit вообще во всём, вот такой он у мамы дотошный.
>>1875545 >А я например с помощью main вычисляю говноучителей в ютубе - кто не знает, эта единственная функция (точнее все семейство из почти десятка вариантов) в которой разрешено не писать return Для вычисления достаточно самого факта, что это на ютубе (кроме конференций). return из main — не аргумент
>>1875638 >13 лет назад был С++ 03. В котором уже было про inline методы внутри классов. Было хуй кобылы. Нормальные практики написания кода даже сегодня не везде проникли, а многие даже опытные программисты пишут в таком же стиле, в котором они писали 20 лет назад. И стандарт тут не причём.
>>1875759 Ассерты изначально предназначены для тестирования кода на этапе разработки, типа юнит-тестов. Если ассерт свалился, значит, в логике программы ошибка. Ассерт - это то, что не должно выполняться никогда, вне зависимости от введённых данных. Обработка ошибок - это другое, она предполагает, что эти ситуации возможны. А ассерты для покрытия ситуаций в духе "квадратный корень положительного действительного числа вернул отрицательное значение".
>>1875718 > чтоб можно было потом эту функцию легко перенести из class scope в namespace scope в хедере. Тогда inline не придётся дописывать Бляяяядь. Анон, помни, такой дебич может сидеть за соседним столом
>>1876015 >указатель на bool Ну тогда если фолд не обязательно, то делаешь вектор/список указателей на твои булы v, потом res = accumulate (v.begin(), v.end(), 0, [](uint32_t res, bool b){ return res << 1 + b;}); >>1874766 й
>>1875910 Это не гайдлайн, это проблемы при разработке архитектуры. Если вдруг у твоего нанимателя появятся деньги на рефакторинг этого дерьма, то об inline ты точно не забудешь. а в шаблонах он нахуй и не нужен
>>1876053 Да не нужен он там, это писали деды до того, как на рынке появились более-менее вменяемые анализаторы кода. Типичный дед --> >>1876126
>>1876161 >пердолить абстракции из костылей из этого и состоит профессия программиста, ну хотя еще из дейли митинов там всяких >нормальном языке с функциональщиной ну хотя я уже понял что программистом ты никогда не работал, а только кукарекаешь на дваче > получая производительность норм там производительность
>>1876181 не заплачь только чмоня, а то серьезные дяди твою тонкую студенческую душонку обидели. И вообще иди laba2 с хаскеля на си переписывай, а то препод не примет, скажет дурачок
>>1875588 >Что значит "терм"? (опционально терм */%) Первичное вырежение >Что значит "первичное выражение"? Число либо (Выражение в скобках) >Чем оно от обычного отличнается? Тем что выражение это (опционально выражение +-) терм. Все же написано.
>>1876098 1. Речь шла не об этом варианте применения inline. 2. Если уж ты об этом заговорил, то и gcc и clang учитывают inline при принятии решения, инлайнить функцию или нет. 3. Компилятор переиграть в нетривиальных алгоритмах достаточно легко.
>>1875826 еще проще: - деление на ноль - это ассерт, и не должно происходить никогда (но в дебаге стоит проверить) - чтение поврежденного файла на диске - это ошибка, бытовая ситуация, и должна обрабатываться всегда (даже если просто падает) - отсутствие строчки в конфиге - это варнинг, должен обрабатываться и исправляться, но не падать
>>1876152 >Да не нужен он там, это писали деды до того, как на рынке появились более-менее вменяемые анализаторы кода. Вот именно, что не нужен. Этого ответа от тебя полтреда и добивались, ебанько.
Кто-нидудь работал с контрольными суммами? Столкнулся с ситуацией, имеется: uint32_t massiv[size] - это 32битный массив. Требуется вычислить его контрольную сумму crc32, вообще ума не приложу как это сделать
>>1876374 Тебя не смутило, что терм это первичное выражение, первичное выражение это выражение, а выражение это терм? Там цикличное определение. Чтобы разорвать цикл нужна воля.
>>1876376 Я это и подметил, тут ошибка в том что я думал, что ход анализа почему то как на пик 1 шел из-за этого те 2 правила ниже не работали б. А вот как обработать тот же пример 2+3 но еще и 5, ведь 2+3 засчитается как выражение, а в синтаксисе терм первичное выражение, а выражение * первичное выражение нету
>>1876404 а чё 3 не проваливается в выражение, а остается в терм. Как будто он ждет пока к нему придет первичное выражение, как будто знает об умножении. Как ход вообще идет? значение и оператор получается. в данном случае 2+ потом 3* потом 5. Так как тогда ход анализа идет? Если как на пик 1 получается пик 2, где все сторопится когда 5 лишний раз преобразовывается в терму, а если как на пик 3, то тогда 2+ не проходит по условию потому что 2+ пока что просто терм, еще в выражение не преобразовавшийся.
>>1876410 Конкретный алгоритм устанавливается в условиях задачи, самое простое - просуммировать все числа массива и взять 4 младшие байта результата (и.е суммировать можно прямо в уинт32)
>>1876431 Конкретная задача такова, есть микроконтроллер российского гавнопроизводства, я написал прошивку для него, у этой прошивки с помощью обычных онлайн калькуляторов можно посмотреть контрольную сумму, то есть там используется полином crc32 ieee, моя задача прочитать память МК, в которую и была записана прошивка, это будет как раз массив uint32_t massiv[size]. Далее мне нужно вот к этому массиву применить расчет crc с использованием полинома crc32 ieee, для того чтобы я мог сравнить то что должно было быть записано в МК, с тем что там записано по факту.
>>1876413 Это называется "жадность", и довольно болезненный вопрос в грамматиках, регулярных выражениях и вот этом всем. Ты встретил 2. Это число. Ты встретил +. Есть правило которое требует слева выражение, справа терм. Слева число которое может быть повышено до выражения. Справа терм. Начинаем набирать терм. Встретили 3, это число, это терм. Встретили ⚹, опа, а там рекурсивное правило. Ведь и 3 терм, и 3⚹5 это тоже терм.
>>1876456 Почему складывать? Я понимаю как получить КС на бумаге, например от 8бит информации применяя полином 3 степени к примеру, тут все соизмеримо, но мне нужно применить к 30кб информации полином 32 степени, вот тут я не понимаю как это должно работать. Были мысли взять КС отдельно от каждых 32бит (это по сути один элемент массива) и потом сложить их все, но будет ли это верно?
>>1876098 сразу скажу что я не разбираюсь в вопросе, но у меня есть подозрение, что и сегодня можно на асме писать куски кода которые будут в разы быстрее отрабатывать, за счет того что будут напрямую использоваться векторные расширения, новые наборы инструкций, плюс программирование с учетом попадания в кеш и прочие оптимизации..
>>1876520 > то и сегодня можно на асме писать куски кода которые будут в разы быстрее отрабатывать Не имеет смысла в плане трудозатрат. > напрямую использоваться векторные расширения Только если вдруг компилятор сам не сможет определить, куда их применить в конкретном случае, что случается достаточно редко. > новые наборы инструкций Каким образом? > плюс программирование с учетом попадания в кеш и прочие оптимизации.. Хуяции. Если ты свою laba2.cc напишешь ассемблерными вставками, лучше в кэш оно укладываться не станет. Это решается разработкой схемы доступа к данным с учетом особенностей кэширования, и то только для конкретного случая, если бенчмарки показали чаще всего просто в качестве превентивного предотвращения false sharing куда-нибудь прихуяривают паддинг в 64 байта > сразу скажу что я не разбираюсь в вопросе Хуле пиздишь тогда?
>>1876565 Мы про случаи "изначально писать ассемблерной вставкой". Если ты начинаешь хуярить это сразу на асме, не спрототипировав и не померив производительность в обычном варианте, то земля пухом.
>>1876469 Попробовал объяснить своими словами и понял что сам не понимаю как Crc32 работает. Ну в общем там какой то аккумулятор, в который по биту засовывают и ксорят )))
>>1876443 >хоть деды <...> использовать Он имел ввиду дедовский способ, руками написанный рекурсивный спуск. Реально, анон, почитай лекции по формальным грамматикам и парсерам, проще будет.
По твоему вопросу: грубо говоря парсеры в каждый момент времени держат несколько вариантов развития событий. И если в какой-то момент попадается символ, который не вписывается в текущее правило, они пробуют другое правило. Если всё равно что-то не так, они отходят на шаг назад и уже там пробуют по-другому. И так, пока не распарсится вся строка до самого конца.
>>1876587 Ладно анон, отложу это на потом. Поясни пожалуйста, парсеры в интернете так и работают: с помощью грамматик находят нужные элементы в html странице?
Сап, ньюфаг в треде, появилась проблема с "winbgim.h" и <string.h>. Проблема заключается в том, что нужно сделать 3-д обьект в консоли с помощью команд (ellipse, line) но что-то я не могу понять за что отвечают числа, к примеру "line (575,400,575,100);" Обычная линия коих много надо =, но за что отвечает первое число (575), и второе, третье? Мне нужно знать какое число отвечает за высоту, ширину, направления. То же самое с ellipse. Буду очень благодарен за ответ, так как только пытаюсь вкатиться.
>>1876650 >line (575,400,575,100) Ну это явно координаты точек Перейди на объявление этих функций, там должно быть понятно хотя бы из имён переменных. Или ищи доки на твою либу.
>>1876644 Не знаю что ты там хотел написать, все звездочки съело. Если ты пытался передвинуть указатель на типа "предыдущий" массив, то это так не работает - между ними может быть целая страница памяти, например.
>>1876726 Смотря какие у тебя задачи. Есть CImg. Есть разные либы для рисования, собственно, 3D. Есть куча либ для 2D если тебе так важно рисовать все линиями и кружочками. В конце концов есть софт для процедурного рисования командами, но не си++. Тот же OpenSCAD.
>>1871393 Пердачую модули и std::format. Лично я жду, когда в стандарт уже завезут нормальный мультиплексированный ввод-вывод, но это произойдёт не в двадцатых плюсах, а когда Networking TS доведут до ума.
>>1876520 Это верно. Часть инструкций процессора невозможно из с++ использовать напрямую. Особенно это болезненно, если ты всякие кодеки дрочишь под эмбед.
>>1876552 stl макака в режиме отрицания? В прошлом треде тебе приводили пример на ASM + SIMD для обработки картинок. Работает в 2-2.5 раза быстрее чем тот же код без вставок на c++.
>>1876650 у тебя не 3d, а 2d. Обычно дело обстоит так: Оконная координатная система имеет начало (0,0) в левом верхнем углу экрана. Ось X вправо, ось Y вниз. Отрезок/линия задаётся двумя точками в этой системе координат. line(x1, y1, x2, y2).
>>1876746 У меня вопрос. Вот есть либа для рисования геометрии opencsg, например. Насколько я понимаю, это только инструмент для визуализации. Если мне туда физику на модельку прикрутить надо, как в CAD/CAE софте. Как дальше работать с этой геометрией? Ведь все эти либы только для визуализации, как я понимаю, а перевести их в сетку с ячейками и получить дальше какой-то динамический массив в виде ячеек необходимо? Есть такие инструменты?
>>1877081 Так а что тебе нужно то? Вся геометрия для CAD и им подобных систем - OpenCASCADE. Нужна физика - Bullet Визуализация расчётных сеток (и операции с ними) - Vtk Всё это пилилось лет 15 и там овердохуя всего. Но не хайтек и работает не очень шустро.
Прошу, анонче, помоги долбоебу(мне) написать программу: 1. В матрице A[n][n] отсотировать строки так, чтобы элементы последнего столбца были упорядочены по неубыванию. Обязательно надо создать функцию, которая меняет местами строки, номера которых переданы как формальные параметры.
С горем пополам написал такой говнокод, однако работает через раз:
void sort_rows(int matrix, int row1, int row2, int columns) { int temp; for (int k = 0; k < columns; k++) { temp = matrix[row1][k]; matrix[row1][k] = matrix[row2][k]; matrix[row2][k] = temp; } }
int sort_matrix(int matrix, int rows, int columns) { int last; for (int i = 0; i < rows; i++) { last = matrix[columns - 1]; for (int k = 0; k < rows; k++) { if (last < matrix[k][columns - 1]) sort_rows(matrix, i, k, columns); } } return matrix; }
Кучу раз переписывал, но работает все ужасно, никак не могу понять саму суть сортировки матриц.
Вавян, они там в интеле совсем охуели, суют мне какую-то oneAPI раздутую ебату. Нет, блять, я не хочу выкачивать 14GB deb пакетов с какой-то шелупонью. подскажи, как обмазаться по минималочке?
Что дешевле, хранить указатель на функцию который инициализируется в начале работы программы и потом вызывать функцию по указателю или же каждый раз проверять булевый флаг и вызывать необходимую функцию по условию? Например есть функция memcpy и хочется на процессорах поддерживающих AVX юзать версию memcpy с AVX, иначе юзать обычную. Какой способ более оптимизированный?
>>1877154 Хм, а чем это обусловлено, ведь и там и там одна операция чтения памяти. Надежда на то, что компилятор заинлайнет обе функции в одно и не придется тратить ресурсы на вызов другой функции? Кстати, а если условие не одно, а несколько (AVX -> SSE -> default) то через свитч тоже быстрее будет?
>>1877152 У Агнера Фога в https://www.agner.org/optimize/optimizing_cpp.pdf секция 13.5 про это. Но вообще, если ты используешь SIMD, то время исполнения функции у тебя в любом случае будет намного больше времени на выбор нужной имплементации, так что я бы не заморачивался.
>>1877081 CSG это "конструкторы" форм из более простых форм путем сложений/вычитаний/пересечений Но в твоей либе четко написано что она меш из них не конструирует, а пользуется приемами типа z-buffer Так что тебе надо искать именно либу которая работает с мешами, или хотя бы делает их из CSG.
Можно к этому моменту завафлить архитектуру или структуры данных.
Вообще, современный оптимизон он в первую очередь про ублажение кеша и про эффективные структуры данных, чем про эффективные датадробительные инструкции.
>>1877343 Насколько помню, там очень мало памяти было, поэтому на ассемблере был написан небольшой интерпретатор, а остальное на некотором DSL. На крестах вряд ли это было бы выполнимо вообще.
Сап, опять ньюфаг в треде, мне тут подумалось, что я сделал хуйню в том посте >>1876650 Я нарисовал цилиндр, но там походу должен был быть вытянутый шестиугольник который я бы уже сделал в 3-д. Так вот, можно ли сделать из цилиндра вращающую модель в консоли? Или там только из шестиугольника можно? В цилиндре 10 точек насчитал (несколько не посчитал), а если я бы сделал шестиугольник там бы было в 20+ точек.
А в MSVC всегда такие хуёвые оптимизации были, или я что-то не так делаю? Мои laba1.cpp практически всегда были в пару раз медленнее, чем если бы я собирал под linux + clang.
>>1878171 Ну а есть вероятность что я пойду на работку устраиваться и меня заставят прямо в линухе возиться? Линукс в целом знаю, но пердолиться не охото.
>>1878197 >>1878201 Сказки это всё. Меня тоже пугали ООП, темплейтами, указателями а я всё налету схватываю ну почти без загвоздок. Ничего, сейчас за полгода неспешно наверну stl, opengl, qt, мультитред, ml и заведу трактор а там через пару лет и собственный стартап.
>>1878204 Ох дружок, у тебя эффект Даннинга-Крюгера просто зашкаливает. Мне это особенно смешно, потому-что был таким же. Все изи схватывал, понимал, а потом на первый собес пришел и ответил еле еле на пару вопросов из 20. Настолько плохо, что мне прям на собесе сказали, какие книги почитать еще, даже не "мы вам перезвоним".
>>1878201 Да вполне возможно. Да, даже спустя кучу времён ты будешь узнавать какие-то мелочи или нюансы и говорить "вау, вот это ж нихуя себе", хотя, казалось бы, уже очень много знал и так. Но так вообще со всеми вещами в жизни, в любой отрасли и профессии. По крайней мере если ты реально стараешься углубляться и развиваться.
Я вот имел уже лет 5 опыта на плюсах прежде чем узнал, что const в namespace scope implicitly static, а не extern, в отличие от С. И потом каких-то таких мелочей с годами было ещё много. И будет ещё.
Салют, пиздюки. Посоветуйте, как лучше всего организовать следующее. Вот я хочу чтоб логи раз в сутки были обновлены. То есть идет переименование файла debug.log в currentdate_debug.log. И вообще можно чтоб эту хуйню в tar.gz пожать.
Если файла нет, то софтина должна создать новый. Ну вы поняли.
Хочу написать скриптик который это делает. Какие подводные? Я же не знаю в какое время приложуха(на сиплюсплюсе) хуярит логи, открывает/закрывает файл. Хочется и чтоб логи не проебались.
Так вот, вопрос не столько по C++ а по потокам файловым. Можно ли в файл в который периодически пишут взять и двинуть командой mv?
>>1878124 По идее проекция круга на плоскость (то бишь камеру) это в общем случае эллипс. Если умеешь рисовать эллипсы, значит по идее можешь рисовать вращающийся цилиндр если применить немного линала.
>>1878191 Нахуя вам блять эти книги, мы в 80 живем без интернета чтоли? Делаешь проектик, натыкаешся на что-то непонятное, гуглишь, читаешь какую-нибудь статейку и все. Пиздец, щас бы сидеть 500 страниц наяривать какой-то хуйни без практического применения.
Гайд по преобразованию 3D-векторов в положение точек на экране. Если у тебя консоль, то сделай таблицу буква : цвет, то есть . это очень неяркий, а B довольно яркий. Если линии нужны антиалиазинговые, то погугли разные алгоритмы для отрисовки линий.
>>1871183 (OP) Сап байтоебач. Есть функция на Си и ее интерпретация на асме, пик тотали рилейтед. Казалось бы, компилятор должен выделить 16 байт под буфер и 4 байта под флаг, и тогда стек должен выглядеть как на рисунке 1, но нет, он выглядит как на рисунке 2. А именно -- флаг, 12 байт непонятной хуйни, 16 байт буфера, 8 байт указатель (типа в регистре он их оставлять не хотел) и еще 8 байт выделенных хуй знает зачем. Больше всего меня беспокоят 12 байт между флагом и буфером, т.к. от этого зависит, как будет работать эксплойт через переполнение буфера. Через компилер эксплорер код прогнал, гцц и клэнг выдают примерно то же самое. Пока что нагуглить смог только canary value, но не уверен, что это оно.
Два вопроса: Список инициализации для конструктора уже был в самом первом стандарте, т.е. C++98? Не могу найти. Начиная с C++11 появились non-static data initializer, а именно int a = 1; в структурах, классах. Как они реализованы? Внутри себя они представляют использование неявного (создаваемого компилятором) списка инициализации?
>>1879111 Не, я ничего не путал, формулировка вопроса была корректная. Про >int a = 1; // since c++11 я знаю, это называется in-class initialization. >Поэтому тебе такой вопросик: какое значение будет иметь a? a будет иметь значение 2, т.к. список инициализации имеет приоритет над in-class initialization. На мой вопрос уже ответили >>1879100
Сразу закину следующий вопрос. Как называется эта проблема на пикриле (как ее правильно гуглить), и как она решается? Это же пиздец. Почему вообще разрешается создавать одноименные классам функции? Сразу на ум приходят ситуации, когда ты в своем большом проекте сделал тысячу классов, потом подключил стороннюю либу, а там определены функции с такими же именами. И что, придется переписывать исходники проекта/либы? Очевидно, что должно быть какое-то нормальное решение
>>1879127 Так а в чём пиздец то? Типичный проект состоит из собственного кода и thirdparty, поэтому от коллизии имён ты никуда не денешься. Обычно код заворачивается в namespace.
>>1879131 Про неймспейсы я сразу подумал, но тут был вопрос, скорее, касательно самого синтаксиса. Просто я к тому, что в плюсах есть много неинтуитивных и не совсем логичных вещей. Например, чтобы вызвать стандартный конструктор класса Foo при определении переменной, то нужно писать Foo a; А если я хочу, например, в функцию f(Foo q, ...) в качестве аргумента передать локально созданный экземпляр класса Foo, инициализированный конструктором по умолчанию, то при вызове надо писать f(Foo(), ...);. Можно же было реализовать это в языке по-нормальному, чтобы было интуитивно, т.е. f(Foo, ...); без круглых скобок. Короче, бугурт
>>1879233 Что же выбрать: мультиплатформенное решение по производительности стоящее на 2 месте или костыльное низкопроизводительное говно привязанное к 1 говноплатформе?
>>1879448 >Ты что-то написал? А что? Простенькую гуишную дб, плеер для iptv, минималистическую копию спотифая, компилятор без оптимизаций в принципе, просто копию tcpdump. Ну и по мелочи для собственных целей. >А что готов писать? За что заплатят хорошо то и напишу.
>>1879442 Ты сейчас про линукс, на котором сидят 2,5 шиза и про мак ос, которым для работы!! надо? Шинда сейчас монополист на рынке всё лучшее на ней, а более худшего не нужно, понимаешь?
>>1879464 Но тем не менее Вулкан показывает лучшую производительность, чем DX12. Плюс Вулкан банально приятнее. А вот OpenGL действительно нахуй не нужен. Разве что для мобилок ES дрочить. Ну или для поддержки древнего железа как резерв.
>>1879467 Ну если не хочешь углубляться, то есть отличные фреймворки с абстракциями над Вулканом/DX11/DX12. Смысла всё так же нет в OpenGL в 2021. Лучше bgfx какой-нибудь использовать, чем говно мамонта ковырять просто потому что оно легче.
>>1879720 Какое-то странное многопоточное шарево, или когда у тебя у тебя адовое легаси без четко очерченного лайфтайма обьектов.
Я буду честен - мне за все шесть лет писанины на С++ ниразу не приходилось использовать шаред поинтеры, т.к. везде было достаточно юника, который иногда даже мувался.
Анончики, ещё одна проблема возникла при расчете CRC32, вообщем ситуация следующая >>есть микроконтроллер российского гавнопроизводства, я написал прошивку для него, у этой прошивки с помощью обычных онлайн калькуляторов можно посмотреть контрольную сумму, то есть там используется полином crc32 ieee, моя задача прочитать память МК, в которую и была записана прошивка, это будет как раз массив uint32_t massiv[size]. Далее мне нужно вот к этому массиву применить расчет crc с использованием полинома crc32 ieee, для того чтобы я мог сравнить то что должно было быть записано в МК, с тем что там записано по факту. Так вот, все работает, crc32 рассчитывается, но возникла проблема, как оказалось онлайн калькуляторы не используют чисто полином ieee, там какие то мутанты, поэтому единственный вариант это смотреть значение crc прям во время работы программы. Ещё раз по порядку, я запускаю программу, там есть переменная которая хранит рассчитанную crc, затем я должен добавить в эту программу define с текущим значением crc, который я только что увидел, это и есть как бы эталон, но вот проблема, как только я впишу туда значение эталона crc, после перезапуска программы crc естественно изменится, так как новая строчка кода появилась. То есть: пусть значение crc32 без добавления строчки с эталоном это Х, У значение crc32 с добавленным значением эталона. Я врубаю прогу, получаю Х, это значение Х я вписываю в эталон и при запуске значение Х меняется на некий У. И в программе я сравниваю Х с У и получаю нихуя, потому что У я не могу знать заранее, как и Х, я их узнаю только после запуска. Вопрос: есть ли способ как-то заранее учесть в программе это, может есть какие-то алгоритмы?
В общем, такая проблема. Есть абстрактный класс А, содержащий описание виртуальных функций. Есть наследник B, реализующий эти функции конкретным кодом. По условию задачи, реализация может быть разной, в этом и смысл. Есть некий главный класс, который должен работать с реализацией типа абстрактного класса А, но должен быть универсальным по отношению к конкретной реализации.
Проблема в том, что в с++ я не могу объявить поле класса типом абстрактного класса А, а потом присвоить этому полю экземпляр конкретного типа B. И по другому никак, т.к. такая архитектура - требование задачи.
Как, собственно, решить этот вопрос, чтобы это было красиво и true way?
>>1880027 Придумал такое решение. В главном классе поле объявляется как указатель на абстрактный класс, а в конструкторе этому указателю присваивается адрес конкретного класса-наследника с реализацией. Вроде работает, но это достаточно true way?
>>1880089 Потому что снижает производительность в большинстве случаев, только на DX9 можно получить немного фпс, это же обётка поверх DX. Его сейчас и так под всякие решейды везде в некроиграх подкладывают, для совместимости и нормального захвата буфера глубины. Правда там ещё пердолинг присутствует, т.к. это всё пилилось под Линукс для вайнопердоль, а Винда уже вторична.
>>1880363 >Какой релиз, это гцц под линух -O1 или -O2. Хотя бы -Og. Так всего 16 байт выделяется, как и можно было ожидать. Можно ещё добавить -fno-builtin, чтобы строковые функции уж слишком не оптимизировались. Без оптимизаций GCC может оставлять кучу фигни для отладки. >паддинг для алигнмента Паддинг для char? Лолват?
>>1880108 ну, к примеру, это причина классической проблемы хранения полиморфных объектов в контейнерах stl, из-за этого приходилось либо хратить указатели или смарт-пойнтеры или использовать другие контейнеры, из того же буста
>>1880268 дак это вечная дилемма: код по настоящему напичканый макросами или шаблонами, очень плохо отлаживать дебаггерами, плюс на нем ломается любое ide, плюс нечитаемые сообщения о ошибках получается что на полную возможностями ide и отладчика можно воспользоваться только если пишешь plain с или приплюснутый си
>>1880429 >-O1 или -O2. Хотя бы -Og. Мне нужно именно объяснить работу эксплойта с переполнением буфера, дан уже готовый бинарник и надо работать с ним. Да и уже с -O1 не выйдет этот эксплоит (нужно перезаписать переменную flag переполнив буфер, с -O1 она даже не на стеке). >Паддинг для char? Лолват? --> >>1879192 → В C треде я предположил, что это потому, что гцц выделяет место под одну переменную и тут же пытается выровнять стек по 16 байт, вместо того, чтобы выделить сразу все переменные и потом выровнять стек. Ну и там пэддинг не для массива чаров получается в таком случае, а для всего остального.
>>1880930 >выровнять стек по 16 байт Вот на это похоже, да. Значит остался вопрос, зачем остался пропуск в 12 байт, хотя он мог спокойно записать туда заспиленный аргумент в strcpy. Ответ: хрен знает, оптимизации же выключены, любые тупости первоначальной кодогенерации не будут потом удалены.
>>1881216 Что? Все собесы во весь FAANG именно такие. Всем похуй кто ты, и что писал. Это интересно хоть как-то будет после нескольких раундов решения задач с литкода.
>>1881228 Могу ебать, иду писать. Если хочешь - оставь свой ник, как напишу проект на несколько лярдов президентов и стану известным оставлю референс для тебя.
Почему у меня vs при исключении кидает меня хуй знает куда? То в исходники вектора, то в файл с асмом. Я хочу что бы только в моем коде все происходило. Как настроить?
>>1881935 > кидается туда, где кинулся эксепшен, очевидно же Блин. Ну это не удобно же. Мне нужно знать на какой строчке моего кода произошла ошибка >>1881940 Just my code включен. Ну поищу что ты сказал
>>1882006 По-разному. Там и стаднартной библиотеки-то часто нет в нормальном виде, а бывает и плюсов нет. Иногда выкатывают свои простые реализации. Ну и smart pointers решают не все проблемы, а те, которые решают, не всегда в эембеде существуют.
>>1882006 В критическом вообще динамическая память не используется, а в какой нибудь чайник думаю сейчас можно и джаву запихать чтобы вообще все - смарт поинтер.
>>1882040 Как вы заебали со своим ДЕВ С++, КОК БЛОКС и прочей некрохуйней. Откуда вы блядь эту дрисню вообще берете.
Есть студия, Есть слион, есть Вскод на худой конец, нет, находят какой-то анальный клоунский пиздец и начинают ебаться в жопу, вместо того, чтобы писать на С++
>>1882095 > некрохуйней > Откуда вы блядь эту дрисню вообще берете. Понятно же, что в методичке к laba1 указано, что нужно качать dev-cpp, borland c++ builder, visual studio 2005, либо ничего не указано, и тогда пикрил.
>>1881950 > Блин. Ну это не удобно же. Мне нужно знать на какой строчке моего кода произошла ошибка Открой окошко со стеком и посмотри на пару строк ниже
>>1882210 А почему смейк лучше для библиотек? Потому-что он нативно работает с вцпкг и конаном, как единственный правильный способ устанавливать библиотеки!
>>1883156 Реальная тема. С помощью профилировщика памяти даже некоторые хитровыебанные утечки находил. >>1883171 А вот тут сложнее. Сэмплирующий профилировщик может только примерную область показать. Но для локализации места тормозов обычно с лихвой его хватает.
>>1883976 Почитать про socket/bind/connect/send/receive, сделать. Потом сделать через select/poll/epoll, сделать А дальше можно и фреймворками типа асио обмазаться
>>1884079 Хуйня твои советы. Чтоб нормально что-то освоить нужна интересная задачка, а не вот эта вот хуета как в вузике - дрочите теорию и упражнения в вакууме.
у меня беда: SHGetFolderPath(NULL, CSIDL_APPDATA, NULL, 0, szPath); пишет в буффер 1 символ C, я когда решил поменять на более старый компилятор, затем вернулся на 142 и всё залило ошибками..... как это чинить и почему ВинАПИ такое говно
>>1884225 Почему? cout - это объект класса ostream, вывод производится через метод перегруженного оператора <<, который принимает rhs аргумент следующим образом: если это rvalue - по &&, если lvalue - по константной ссылке. Где здесь триллион аллокаций?
>>1884450 быстрофикс по поводу rvalue - просто принимает его копию, но rvalue - это литералы без адреса в памяти (std::cout << 4, например), поэтому энивей похуй.
Подскажите начинающему изучение, какую версию Вижуал Студии украсть с торрентов? Раз уж бесплатно, то может сразу Профешнл иди Энтерпрайз? Обесните, когда какая версия лучше подходит пожалиста
>>1884456 У меня куплена professional от работы. Так и не понял, чем она отличается от коммунити, которая дома. По-этому просто скачай бесплатную и не еби голову.
Есть ли в стандарной либе какой-либо класс который принимает контейнер и возвращает индекс и итератор? Короче говоря, для range-based for хочется небольшую оберточку чтобы индекс перед циклом не писать и не инкрементить его в теле
А где можно следить за процессом выкакивания модулей by gcc? Так понимаю что сопутствующей проблемой встанет то, что системы сборки (bazel) также не будут уметь ещё собирать плюсовый проект на модулях?
А ещё интересно было бы вкатиться в системы сборки. Стоит предо мною дилемма, cmake или bazel. Вроде Базель намного проще удобнее и современнее, но смаке используется везде и на него наверняка документации побольше.
>>1884445 Ну хуй знает. Форматный вывод в потоки это еще более ебанистическая залупа, чем даже сами потоки. Что угодно, включая snprintf, лучше чем пятистрочный пердолинг с ио-флагами и модификаторами (которые еще и имеют меньше возможностей, чем тот же принтф)
>>1884331 Они конечно говно, но 1. Винапи это C, плюсы тут ни при чем 2. MFC придумали до вменяемой стандартизации плюсов, отчасти поэтому оно такое как есть. Не нравится не ешь. Есть Qt, есть шарпик. 3. COM. Он велик и ужасен, но часто без него никак. Смирись. Ну и доки всё же лучше читать. Потому как смотря на тот скрин видно не хитровыебаную проблему, а незнание char, wchar_t, TCHAR, и того с чем винда нативно работает.
>>1884541 Тем что у тебя скорее всего ещё msdn подписка. Ну и тонкости лицензирования. Вот в Enterprise да есть клёвые фичи, но и без них прожить можно
Ананасы, пытаюсь применить std::lower_bound к вектору пар std::pair<unsigned long, unsigned long>. Условие моего поиска таково - я хочу найти число, которое падает в ренже между двумя значениями в паре.
Пример: вектор пар {1000, 2000}, {2000, 4000}, {6000, 10000}, число, задаваемое при поиске - 3000. Цель - при вышеперечисленных данных, вернуть итератор на пару {2000, 4000}, ибо 3000 находится между ними. Пытался написать через функтор, лямбду - возвращает неверное значение. Буду рад, если подскажете можно ли это красиво и чисто написать, не хуяря от руки кастомный бинарный поиск?
>>1884903 >Ну так правильный то вариант - fmt все таки, а не выбор из двух стульев. Да, но она пока ещё только в виде отдельной либы, так что всем сосать.
>>1884924 Хард мод: сетевой стек, модель слоев OSI, протокол TCP/IP, HTTP(S), значит обработку строк, эллиптические кривые для SSL, WinAPI раз у тебя папки, а не директории, многопоточность, ты же не собираешься сидеть до второго пришествия.
>>1884923 Почему ты считаешь что это работа для lower_bound? Его семантика именно бинарный поиск >Пытался написать через функтор, лямбду Какая разница через что писать, лол? Упрости задачу и напиши сначала для вектора просто чисел, типа ищешь 3000 среди 1000, 2000, 3000, 4000
Есть класс базовый Widget. У него есть метод добавления\вызов каллбека по имени. От widget наследуется класс MenuBar файл, правка, вид и тд. У этого класса есть метод добавления пункта меню: текст кнопки и имя каллбека. Соответственно, чтобы всё работало как задумано нужно добавлять пункт меню, а затем добавлять калбек. Стоит ли сделать так чтобы при добавлении можно было сразу добавить калбек (этот уже не будет связан с базовым классом и им будет управлять производный класс)?
>>1884981 Сейчас все на удалёнке сидят. Из "условий работы" в большинстве случаев остались только деньги и ДМС. Из отечественных контор всё как обычно: Яндекс, банки, Лохсофт. Есть куча зарубежных жирных контор типа Хуавеев, но ты туда сразу не вкатишься.
>>1884980 Однако, как мы оба знаем, грань параллелепипеда представляет собой четырехугольник, все вершины которого лежат в одной плоскости. Видимо в задаче и надо найти такие четыре точки в исходном списке или показать что их нет.
Есть две плоскости, заданные уравнениями (на компьютере это 4 коэфицента a,b,c,d перед x,y,z соотв). Как мне определить, что плоскости параллельны, но при этом различны?
>>1885059 Ты тестовое на младшенького в гейдев пишешь? Подсказка: тебе помогут векторное и скалярное произведение. (a,b,c) это вектор нормали к плоскости.
>>1884978 >Да, типичные для C именования в стиле CamelCase и в стиле МНОГАРАНДОМНЫХБУХВ. Венгерская нотация, наследие древности.
>Qt появился 25 лет назад. Ламповый 4.0 вышел в 2005 задолго до modern c++11.
MFC появился 28 лет назад. С++ хоть сколько-то стандартизировали 22 года назад. К сожалению, МС забила на MFC году так в 2003-2005 и стала продвигать .NET, оставив с++ без вменяемого GUI (и средств его разработки). Сколько-нибудь значимое изменение - в 2008 году купили слепок кода у BCG, но дальше развивать не стали. Сейчас двигают UWP - но многих вещей на нём не сделать.
>Без ATL/WTL ты на нём просто охуеешь писать. Тут согласен. Да и с ними тоже можно охуеть (когда пишешь компонент, а не используешь).
>Смотри не перепутай Ну тут всё просто (см первый ответ). Но мой посыл был про то, что надо использовать _UNICODE и -W версии функций. И не кастить wide строки к char (а если очень хочется - то не к разным codepage а конвертить в UTF-8 через WideCharToMultiByte например)
>>1885045 >А сама эта нуль-терминированная строка где хранится в это время? Вот этот >>1885083 прав. Сама SSO - довольно интересная штука, посмотри её устройство.
>>1885137 >может функция c_str() конструирует временный объект? Нет, потому что
The elements of a basic_string are stored contiguously, that is, for a basic_string s, &⚹(s.begin() + n) == &⚹s.begin() + n for any n in [0, s.size()), or, equivalently, a pointer to s[0] can be passed to functions that expect a pointer to the first element of a null-terminated (since C++11)CharT[] array.
>>1885137 Нет. Внутри std::string есть m_size и m_pointer. Если строка длинная (больше, чем sizeof(m_size) + sizeof(m_pointer)), то в куче выделяется память и туда записывается текст в конец которого ставится /0; m_pointer указывает на эту память. Именно он и возвращается c_str() или data(). Если строка короткая, то имеет место small string optimization. За правильную реализацию не скажу, но возможно как-то так: Первый бит m_size указывает, что строка короткая или длинная. Следующие 7 бит хранят длину строки. Сама строка записывается поверх памяти [m_size]+[m_pointer] со 2 байта (m_size и m_pointer лежат в памяти на стеке последовательно). В конце пишется /0. Соответственно функции c_str() и data() возвращают указатель на 2 байт m_size. Но в любом случае никаких буферов для конвертации в C строку не создаётся. Поправьте, кто в теме.
>>1885152 В целом ты прав, а в частности в каждой реализации может быть по-своему (+ доп извраты в Debug) и меняться от версии к версии, впрочем, MS например заморозили ABI на v140 тулсете и пока не меняют, но собираются - для реализации каких то новых фич придется сломать бинарную совместимость.
>>1884834 А ты довольно немногословен Может хоть расскажешь почему стоит использовать скнс, который ещё менее популярен чем Базель, значит ещё больше проблем с внешними проектамм
Мне надо написать приложуху, которая будет пиздеть с разными устройствами по сети. Собирать с них данные и передавать другим классам, которые их неким образом обработают.
Так вот. Сейчас есть класс Device от которого отнаследованы несколько классов, которые непосредственно пиздят с железом. При этом внутри класса Device есть классы, предназначенные для хранения устройство-специфических данных. Классы для хранения точно так же наследуются в классах, предназначенных для работы с конкретным железом.
По идее, подход не совсем правильный, и классы для хранения данных нужно вынести отдельные файлы, чтобы в другом проекте, gui-приложухе (куда эти данные попадают с сервера), использовать только их, а не тянуть ненужные классы для работы с железом по сетке (они по факту нужны только на сервере).
В итоге, получилось так, что написано криво и надо бы это переделать. Но меня уже давно напрягает то, что многие проблемы проектирования являются неочевидными и становятся видны только после того, как ты написал код или в процессе.
К чему я всё это: посоветуйте литературу, которая разъясняет, как проектировать иерархию классов/наследования, как грамотно придумывать взаимодействие между ними и всякое такое. На своих ошибках учиться больно уж геморно и времязатратно.
>>1885191 Посмотри книжки по: - рефакторингу (Фаулер "Refactoring - Improving the Design of Existing Code") - паттернам проектирования (Гамма и ещё 3 мудака "Design patterns") - операционным системам (Танненбаум "Modern operating systems") Сильно не упарывайся, просто вникни как на каждом уровне решаются архитектурные проблемы.
>>1885045 string это класс, у него есть мембер - указатель на char, а также какой-нибудь unsigned long buff_len, который хранит инфу о длине аллоцированной строки. Метод c_str возвращает указатель на начало этой строки в памяти. На вопрос где это находится - в куче, ибо размер строки неизвестен заблаговременно в компайл тайме. Деструктор класса string потом удаляет выделенную память.
Long story short - за кулисами это работает как в сишке (если посмотреть на реализацию внутри класса string), просто ввиду присутствия ООП в плюсах, сию сырую ебанину можно обернуть в класс.
>>1885365 Какой string? Где? Тебе же написали выше - implementation defined. Там может хоть на лету создаваться, язык такого не запрещает. Язык определяет только интерфейсы, интерфейс говорит что при вызове c_str() ты получишь нуль-терминированную строку, все. Если тебе интересно как сделано конкретно в gcc там и смотри сам https://gcc.gnu.org/onlinedocs/gcc-4.6.2/libstdc++/api/a00770_source.html
А как называется структура данных (дерево какое-то), когда количество узлов может быть любое у каждого узла дерева и глубина ветвления не ограничена друг относительно друга? M-Way Tree - это оно?
Как сделать строгий алиас к типу? Например, хочу передавать строку в функцию: в одном случае имя текстуры, а в другом текст. Т.е. будет две перегрузки.
>>1885602 не, сильные алиасы это крутотенюшка, другое дело, что они не стандартизированы, и никто не знает, как их правильно готовить. Но, оверолл, я бы с удовольствием пользовался, будь оно в стандарте
>>1885144 >оставив с++ без вменяемого GUI (и средств его разработки) можно писать для UWP на стандартном с++ 17 с использованием winrt, это будет чистый с++, не расширение с++/cx другое дело что никто этого не делает, лол, тк шарпик есть
>>1885144 >оставив с++ без вменяемого GUI (и средств его разработки) При всей моей любви к сиплюсплюсу, гуи я буду писать на шарпе на Avalonia. Потому-что так проще и быстрее, хоть я и шарп знаю сильно хуже.
Не бейте сильно, решил поучить ваш язык, дошел до указателей и не понимаю во что int counter_p = new int(7); std::cout << counter_p << ' ' << counter_p << std::endl; delete counter_p; std::cout << counter_p << ' ' << *counter_p << std::endl;
На выходе получаю 0x7f9131c05900 7 0x7f9131c05900 7
Непонятно именно последнее. Память мы освободили ведь, почему нет ошибки? Т.е. даже компилятор не ругается и варнингов нету.
>>1885663 Клоун, пидрас, троль, мразь, ублюдок, гнида, падаль, тварь, чудище, уебок, чмоня, лошок, ебаный ты чел, где этот выход находится??????????????
>>1885669 >>1885670 >>1885672 Клоуны, пидрасы, троли, мрази, ублюдоки, гниды, падлицы, твари, чудики, уебки, чмоньки, лошки, ебаные вы челы, прямо сейчас объясняете как получается такой вывод без всяких умных слов
>>1885674 >прямо сейчас объясняете как получается такой вывод без всяких умных слов Открываешь исходники ядра и читаешь про файловые дескрипторы, а именно про stdout. Ну что ты как маленький.
>>1885673 Там уже нечего учить. + Я исписался. Уже 2 проекта на гите запилил, 100 звёзд суммарно получил. И Майерса этого вашего прочёл. Дальше что делать?
>>1885684 >Мм, работу искать? Да не, рано ещё. Мне не поверят если я к своим 3 месяцам вката плюсану до требуемого кол-ва в вакансии. Ну и Крюгер этот ваш вроде не мучает - понимаю что многого ещё не знаю, наверняка загнусь на собесе, нужно хоть какую-то технологию освоить на более-мене серьёзном уровне.
>>1885690 >boost.asio >qt Как раз их в проектах и юзал, лол. Но ничего серьёзного без лютого чтения доков. Чат мб попробую. Сейчас на выходных по приколу opencv по туториалам копаю, но наверное буду qt осваивать. >тут надо смотреть, что в твоем городе больше требуется на джунов. Да я из Московии, тут вакансий хватает. Думал сначала тут вопрос задать прежде чем оттуда что брать.
>>1885692 Не, пока не стану. Там деанон сразу будет, сори.
>>1885740 Ты пытаешься освободить память, которую не брал через new. Конечно будет ошибка. >>1885767 Конечно не понимает. Зуб даю, что 90% кто доходил до указателей и ссылок, обсирались не хуже.
Народ, а хуле вы крестовики не пользуетесь зумерскими технологиями, такими как менеджер зависимостей типа maven/npm, нормальными тестами, шоб можно было TDD ебошить как нормальнеый чел.
Поцоны, а вы в принципе зачем плюсы учите, если сейчас платят где угодно больше при меньшем затрате усилий? Разве что в геймдев идти, который в России в парочке компаний и в десятке инди студий с копеечной зп?
>>1885938 Устроился джуном в родном Киеве за 30к местных рейхсмарок в то время когда на всякую жсо, хпх и жава/шарпопарашу зп у похожих вакансий начинаются от 8-10к.
>>1885938 Бля моча банит за хохлов не приятно конечно! Аж роутер перезагрузить пришлось! Ну а по твоей теме, на плюсах же самое серьезное и интересное пишется. Нахуй блять эти ебаные сука месенджеры кому нужны будут через пару лет.
>>1885920 Какой язык - такой и тулинг. Несколько реально используемых компиляторов, несколько способов подключения либ, много зависящих от реализации фич, плохо скрываемая низкоуровневость - попробуй в таких условиях написать универсальный менеджер пакетов хотя бы.
Есть алгоритм на C++, там много файлов и h, и cpp, но графику гораздо удобнее прописать на python. Как можно вызвать функцию в которую вложено дохуя других функций из питона? Учить CLI нет ни времени, ни желания надо сдать проект в уни. Про C API знаю, но можно ли там, допустим, написать функцию, которая принимает аргументы из питона, форматирует их и вызывает нормальные cpp функции, без переписывания их всех?
>>1886126 Построение пути объекта, то есть задание препятствий (рисование фигур) в реальном времени, задание начальных и конечных координат, потом отображение пути.
Как пропарсить массив через инжектор заднего индекса? Чтобы без передней индексации консольной, а сразу напрямую в кеш? Может это есть в стандартной библиотеке?
>>1886260 Нам версионирование нужно только во внутренних либах, просто впилили говноскриптик, который создает новый пекедж и меняет vcpkg.json в проекте. Приятно.
Но ваще версионирование они обещали в этом месяце.
У меня есть прога на плюсах где просто дохуя вычислений надо сделать. Она по времени немного не заходит. (Вычислений столько, что дано аж 7 секунд). Может ли смена крестов на си без использования всяких std::min улучшить ситуацию?
>>1886306 > нет, алгоритмы чини Там невозможно что то радикально изменить. Я посчитал примерно, какой минимум действий надо сделать и собственно его сделал > или параллель Так вроде нельзя на олимп проге
>>1886332 Нет. Далеко не всегда. Там даже пишут часто, что жюри не гарантируют решение на всех языках программирования, а только на одном конкретном. Обычно это плюсы. Но может быть еще что то.
>>1886495 How to parse an array through a back index injector? So that without front indexing the console, but directly directly to the cache? Maybe it's in the standard library?
А нельзя как то visual studio сказать, чтобы она код наполовину скомпилировала? Она же генерирует промежуточнвй какой то плюсовой код. Вот можно его получить? Это как раз и будет хуйней нечитаемой, да?
Решил обмазаться говном и ПОКОМПИЛИРОВАТЬ gzdoom, и тута ошибка что _First это константа и ее нельзя присваивать, и это в стандартной билиотеке std::sort, а в других версиях если погуглить не было этого const, как вобще такое решать и откатить на старую STL библиотеку, ну пиздец же как вы на этом погромируете
войны синих крестов, кто из анонов с опытом 1-2+ года может просмотреть и указать на ошибки обосрать мой код? важный проект, уже чую говно от себя, еще совсем зеленый, нужна маломальская помощь...
>>1887567 Ты обратился по адресу. В этом треде собрались настоящие профессионалы, способные обоссать кого угодно, независимо от качества и даже наличия кода. Кстати, пошел нахуй.
Как задоджить эту парашу? Есть ли способ? Не хочу зашквариться аккаунтом калософта. Очевидный совет перейти на линь очевиден но визуалка увы слишком удобная.
пацаны, кто-нибудь за 500р сделать сможет на C++? по срокам: до утра 24.12.
0.2.20 Выдача банком кредитов Описание предметной области Вы являетесь руководителем информационно-аналитического центра коммерческого банка. Одним из существенных видов деятельности Вашего банка является выдача кредитов юридическим лицам. Вашей задачей является отслеживание динамики работы кредитного отдела. В зависимости от условий получения кредита, процентной ставки и срока возврата все кредитные операции делятся на несколько основных видов. Каждый из этих видов имеет свое название. Кредит может получить юридическое лицо (клиент), при регистрации предоставивший следующие сведения: название, вид собственности, адрес, телефон, контактное лицо. Каждый факт выдачи кредита регистрируется банком, при этом фиксируются сумма кредита, клиент и дата выдачи. Классы объектов Виды кредитов (Название, Условия получения, Ставка, Срок). Клиенты (Название, Вид собственности, Адрес, Телефон, Контактное лицо). Кредиты (Вид кредитов, Клиент, Сумма, Дата выдачи). Развитие постановки задачи Теперь ситуация изменилась. После проведения различных исследований выяснилось, что используемая система не позволяет отслеживать динамику возврата кредитов. Для устранения этого недостатка Вы приняли решение учитывать в системе еще и дату фактического возврата денег. Нужно еще учесть, что кредит может гаситься частями, и за задержку возврата кредита начисляются штрафы.
>>1887862 >Вы являетесь руководителем информационно-аналитического центра коммерческого банка. >кто-нибудь за 500р сделать сможет на C++? Проорал на всю квартиру
>>1887862 ну чего, эту хуйню никто не напишет? вам же легко, час работы, ну два. в кфц на 500 сходите: вечером просрётесь. а я работу утром сдам, все в плюсе. если есть желание, напишите: vk.com/id535378572
Короче начал слушать цикл лекций от майл сру на тему углублённого с/с++. Дошёл до шаблонов, и извращений с ними, знатно охуел. Стоит ли залезать в них глубже или нет? До этого вроде всё понятно объяснялось.
>>1871183 (OP) Щас в перший раз за несколько месяцев зашел на хабр и внезапно обнаружил, что мне с нихуя дали возможность пригласить одно тело. Не пойму за що. У меня всего одна статья с 29 голосами и рейтинг 8. Активность на хабре около нулевая последний год. У кого сейм?
Помогите, как сделать текст читабельным? Ощущение, будто после каждой буквы пробел стоит. Заходил в свойства консоли отладки и менял шрифты, но "пробелы" все равно остаются. Заодно зацените, это я сам написал (почти)