I worked with one and it was a pain to use. It was a cartridge made of static ram; the computer would write the contents to the cartridge and you would manually reset the console. it was slow, the upload would sometimes fail and there was no way to communicate anything back to the computer. We were using an assembler under MSDOS to make the games.
Was it a dev kit officially licensed by Nintendo or was it third party?
We had both: we had an official Nintendo one that we were given by them, and we had a few from a company called "Cross Products"
При всем огромном уважении к трудам автора, все что написано в началье статьи является, мягко говоря, неправдой.
Абсолютное большинство разработчиков игр для NES/Famicom подписывали договор с Nintendo (включая NDA), и получали и dev версию консоли, и компилятор, и исчерпывающую документацию. Были товарищи, которые пытались выпускать игры мимо N, но это было исключение из правила.
И Nintendo это было супер выгодно. Ибо много игр делали консоль более привлекательной. И она еще и зарабатывала деньги с каждого выпущенного картриджа.
Может стоит все-таки признать, что содержание и корректность важнее, чем картинка с дикобразом и аллегории из серии "кролики скачут друг на дружке в норе и месят глину"?
Я не эксперт по биологии, но в C++ разбираюсь чуть лучше автора сего графоманского опуса. Это типичный материал в духе "стремительным домкратом", написанный человеком, который "плавает", что в юникоде, что в языке C++, что в игровых движках, что в истории вычислительной техники.
Перечислю только некоторые грубые ошибки и неточности, которые сразу бросились в глаза.
Главная магия фиксированных массивов в том что они живут на стеке. Объявление char buf[N] резервирует байты прямо там и гарантирует что черепаха всегда дома.
Наглая ложь. Кроме стека, массив в Си может быть глобальным или находиться в куче. Если поле типа char buf[N] объявлено полем в структуре, то вообще невозможно сказать, где этот массив будет находиться.
Литералы (...) помещаются в секцию .rodata, которую операционная система помечает как read only после загрузки программы. Попытка записать туда что-то вызывает немедленный segfault
Секция .rodata это секция в файлах формата ELF, который не имеет вообще никакого отношения к языку C++ и его стандарту. Равно как и к стандарту языка Си. А еще ELF файл может быть загружен операционной системой, которая не поддерживает защиту памяти (например, из-за аппаратных ограничений). Поэтому немедленного segfault может и не быть.
std::string (C++03/11)
Нет никакого C++03/11. C++03 это абсолютно минорный апдейт стандарта C++98. Стандарт C++11 это революция в языке, "совершенно новый язык".
Поэтому C++03 и C++11 в одну кучу будет смешивать только тот, кто вообще ничего не знает про эти стандарты.
И так же не знает, что std::string появился в C++98.
В природе в принципе не существует стандарта C++ в котором нет этого типа, поэтому приписки типа "C++03/11" это бессмыслица.
Добавили RAII, методы, автоматическое управление памятью
Это просто набор случайных слов. Добавили классы с конструкторами, деструкторами и методами. Автоматические управление ресурсами (в том числе памятью) через вызов конструктора и деструктора стали называть RAII.
хватает классических проблем с (...) весёлой и порой непредсказуемой работой SSO
А можно поподробнее? Где там веселье и непредсказуемость? По слухам какая-то магия? Кролики съели кошачий корм, а обиделись на них за это рыбки?
Каждый раз когда строку передавали в функцию через const std::string& существовал риск, что внутри функции кто нибудь хитрый создаст новую строку из литерала для сравнения
В примере, который это иллюстрирует, никто новую строку ВНУТРИ функции не создает. Строка создается снаружи. Просто для того, чтобы соответствовать аргументам функции compare().
И я в упор не вижу описанного риска, ибо сравнение внутри функции будет выглядеть как s == "abc".
Понимания мотивации создания string_view у автора нет.
Просто посмотреть это теперь вообще философия C++17 - меньше копирования, больше умных view типов и больше производительности через zero cost абстракции и мелкие хаки.
Я хорошо знаю стандарты и "просто посмотреть" это не философия C++17. Это просто кто-то разогнался на собачках, кошечках, кроликах и незаметно для себя дошел до оценки философии стандарта языка, который толком и не знает.
На string_view теперь пишут высокопроизводительный код хитро организуя время жизни полноценных строк.
Точно такой же высокопроизводительный код писали и будут писать на основе std::string.
И нет тут никакой хитрости. Если ошибешься с временем жизни, то получишь "немедленный segfault".
В 1998 году вышел C++98 со своим std::string
Таааак! Так вон же выше написано, что тип появился в C++03/11! "К середине 2000-х годов std::string стал стандартом".
Попытки подружить QString со std::string приводили к созданию временного QByteArray через toUtf8
Конвертация QString в string опирается на локаль операционной системы, которая, мягко говоря, далеко не всегда UTF-8.
И вообще, зачем впихивать невпихуемое и юникод строку утрамбовывать в тип, который не предназначен для хранения такого рода данных?
Конструкции вроде str.toLower или str.split вообще издалека можно спутать с Python
Та ладно! Их можно спутать с любым языком, где есть класс строка с методами. А именно Java, C#, JavaScript, Swift, Kotlin, Go, Scala... Что ж мы так рано остановились?
Вся магия как обычно в Qt спрятана глубоко в PImpl и внутри их мета системы, которая по слухам умеет всё.
Большинство классов в Qt построено на PImpl. И что? К чему это?
И мета система к вещам типа QString::split() вообще не имеет никакого отношения. Такая вот магия. По слухам.
Windows пошла своим путём и выбрала 16 бит, потому что их API базировался на UTF-16, но это были свои, уникальные 16 бит.
Ничего уникального не было. Это был и есть стандарт UTF-16 LE.
а MacOS вообще начала отходить от wchar_t в сторону собственной реализации
MacOS никуда не отходила. В качестве юникода был выбран стандартный UTF-16.
В компиляторах на платформе wchar_t был UTF-32. Плюсы на маках всегда были гражданами второго сорта, поэтому Apple тут просто спустила все на тормозах, вместо того, чтобы привести в соответствие.
Попытки конвертировать между std::string и std::wstring на Windows превращались в многочасовое путешествие по документации
Как я уже писал выше, потому что это неоднозначное и очень опасное преобразование само по себе. Как значение double сохранить в char. Ну или как пенис слона засунуть в вагину кролика, если использовать более близкие к статье аналогии.
И даже в эпоху, когда не было LLM, даже программисты, никогда в жизни не видевшие Win32 API, в течении минуты находили MultiByteToWideChar и WideCharToMultiByte.
до появления std::filesystem в C++17 единственным способом открыть файл с нелатинским именем на Windows было конвертировать путь в std::wstring и использовать нестандартные расширения компилятора
Ложь. До появления "просто посмотреть" стандарта (в котором, наверное, и файлы открываются исключительно в режиме "только чтение", чтобы только посмотреть) существовал тысяча и один способ открыть файл с юникод именем под Windows.
Например, используя функцию CreateFileW().
Или через boost filesystem.
Или через QFile.
Или...
Если вы посмотрите на malloc в стандартном std::string (...)
То вы его там будите очень долго искать. И не найдете.
Потому что по стандарту std::string обязан использовать new char[].
Вся архитектура, весь networking, весь рендеринг были заточены под коридоры и арены жанра. И строки в движке были утилитарными инструментами для этой цели - имена уровней, названия оружия, debug сообщения, network packets.
Строки это строки. Они никак не были "заточены" под коридоры и название оружия. Ходили слухи, что там была какая-то магия и их даже можно было использовать для имен собачек, кошечек и утконосов.
МакКарти внес фундаментальную идею о неизменяемых объектах-идентификаторах: в программах идентификаторы сравниваются тысячи раз но создаются редко. Имена переменных, функций, классов - всё это известно на этапе написания кода и почти не меняется в рантайме, тогда зачем сравнивать их посимвольно каждый раз?
Да, да, классы в LISP 60-х годов. У которых почти иногда никогда редко не меняется имя в рантайме.
Или это мы в C++ программе постоянно посимвольно сравниваем имен классов и переменных? И почти иногда всегда меняем в рантайме... Магия!
Читать просто невозможно. ИИ нагенерировал главу для учебника по биологии с каким-то бесконечным количеством грубейших ошибок. В области C и C++, разумеется.
Всё как в дикой природе - волк с собой счётчик овец не носит.
Какой волк, какой счетчик овец? Это техническая статья или постмодернистские галлюцинации?
Главная магия фиксированных массивов в том что они живут на стеке.
Во-первых, нет никакой магии. Во-вторых, фиксированные массивы не живут на стеке. Они вообще не живут. Их расположение определяется местом, где они определены и это далеко не всегда стек.
вы можете сами это посмотреть в исходниках, которые все еще доступны на гитхабе
Типичный LLM ход.
Весь этот бред разбирать не вижу никакого смысла. Это просто мусор.
вне зависимости от операционной системы, схема в большинстве сценариев должна быть плюс минус одинаковая -- поток уходит в ОС с ожиданием набора различных событий (например, появление данных на сокете) и одно из этих событий -- запрос извне на завершение потока все, не надо ничего выдумывать
Частно нейронки работают по довольно таки старым базам. Например, бесплатная версия ChatGPT это до сих пор база лета 24-го года. Поэтому о многих свершившихся событиях они пишут в будущем времени, мол ожидается, запланировано и т.д. Спалил на этом довольно много местных статей.
Eurocom это как раз то самое исключение из общего правила.
Если ты маленькая никому на хрен не известная компания в UK, естественно, пробиться на платформу официальным путем было не просто.
Совершенно точно существовали и официальные dev kits и от сторонних компаний.
Вот тут чувак пишет о личном опыте работы с ними: https://retrocomputing.stackexchange.com/questions/1135/what-was-nintendos-software-development-environment-for-nes-games
При всем огромном уважении к трудам автора, все что написано в началье статьи является, мягко говоря, неправдой.
Абсолютное большинство разработчиков игр для NES/Famicom подписывали договор с Nintendo (включая NDA), и получали и dev версию консоли, и компилятор, и исчерпывающую документацию.
Были товарищи, которые пытались выпускать игры мимо N, но это было исключение из правила.
И Nintendo это было супер выгодно. Ибо много игр делали консоль более привлекательной. И она еще и зарабатывала деньги с каждого выпущенного картриджа.
можно попробовать затащить wasm и через него уже компилировать любую экзотику
наверное, стоило сразу уточнить, что речь про compile-time полиморфизм
И это я еще на написал, про возможность в лоб использовать имя, закодированное в текущей локали.
Может стоит все-таки признать, что содержание и корректность важнее, чем картинка с дикобразом и аллегории из серии "кролики скачут друг на дружке в норе и месят глину"?
Я не эксперт по биологии, но в C++ разбираюсь чуть лучше автора сего графоманского опуса. Это типичный материал в духе "стремительным домкратом", написанный человеком, который "плавает", что в юникоде, что в языке C++, что в игровых движках, что в истории вычислительной техники.
Перечислю только некоторые грубые ошибки и неточности, которые сразу бросились в глаза.
Наглая ложь. Кроме стека, массив в Си может быть глобальным или находиться в куче.
Если поле типа char buf[N] объявлено полем в структуре, то вообще невозможно сказать, где этот массив будет находиться.
Секция .rodata это секция в файлах формата ELF, который не имеет вообще никакого отношения к языку C++ и его стандарту. Равно как и к стандарту языка Си.
А еще ELF файл может быть загружен операционной системой, которая не поддерживает защиту памяти (например, из-за аппаратных ограничений). Поэтому немедленного segfault может и не быть.
Нет никакого C++03/11. C++03 это абсолютно минорный апдейт стандарта C++98.
Стандарт C++11 это революция в языке, "совершенно новый язык".
Поэтому C++03 и C++11 в одну кучу будет смешивать только тот, кто вообще ничего не знает про эти стандарты.
И так же не знает, что std::string появился в C++98.
В природе в принципе не существует стандарта C++ в котором нет этого типа, поэтому приписки типа "C++03/11" это бессмыслица.
Это просто набор случайных слов.
Добавили классы с конструкторами, деструкторами и методами. Автоматические управление ресурсами (в том числе памятью) через вызов конструктора и деструктора стали называть RAII.
А можно поподробнее? Где там веселье и непредсказуемость? По слухам какая-то магия? Кролики съели кошачий корм, а обиделись на них за это рыбки?
В примере, который это иллюстрирует, никто новую строку ВНУТРИ функции не создает. Строка создается снаружи. Просто для того, чтобы соответствовать аргументам функции compare().
И я в упор не вижу описанного риска, ибо сравнение внутри функции будет выглядеть как s == "abc".
Понимания мотивации создания string_view у автора нет.
Я хорошо знаю стандарты и "просто посмотреть" это не философия C++17. Это просто кто-то разогнался на собачках, кошечках, кроликах и незаметно для себя дошел до оценки философии стандарта языка, который толком и не знает.
Точно такой же высокопроизводительный код писали и будут писать на основе std::string.
И нет тут никакой хитрости. Если ошибешься с временем жизни, то получишь "немедленный segfault".
Таааак! Так вон же выше написано, что тип появился в C++03/11! "К середине 2000-х годов std::string стал стандартом".
Конвертация QString в string опирается на локаль операционной системы, которая, мягко говоря, далеко не всегда UTF-8.
И вообще, зачем впихивать невпихуемое и юникод строку утрамбовывать в тип, который не предназначен для хранения такого рода данных?
Та ладно! Их можно спутать с любым языком, где есть класс строка с методами. А именно Java, C#, JavaScript, Swift, Kotlin, Go, Scala... Что ж мы так рано остановились?
Большинство классов в Qt построено на PImpl. И что? К чему это?
И мета система к вещам типа QString::split() вообще не имеет никакого отношения. Такая вот магия. По слухам.
Ничего уникального не было. Это был и есть стандарт UTF-16 LE.
MacOS никуда не отходила. В качестве юникода был выбран стандартный UTF-16.
В компиляторах на платформе wchar_t был UTF-32.
Плюсы на маках всегда были гражданами второго сорта, поэтому Apple тут просто спустила все на тормозах, вместо того, чтобы привести в соответствие.
Как я уже писал выше, потому что это неоднозначное и очень опасное преобразование само по себе. Как значение double сохранить в char. Ну или как пенис слона засунуть в вагину кролика, если использовать более близкие к статье аналогии.
И даже в эпоху, когда не было LLM, даже программисты, никогда в жизни не видевшие Win32 API, в течении минуты находили MultiByteToWideChar и WideCharToMultiByte.
Ложь. До появления "просто посмотреть" стандарта (в котором, наверное, и файлы открываются исключительно в режиме "только чтение", чтобы только посмотреть) существовал тысяча и один способ открыть файл с юникод именем под Windows.
Например, используя функцию CreateFileW().
Или через boost filesystem.
Или через QFile.
Или...
То вы его там будите очень долго искать. И не найдете.
Потому что по стандарту std::string обязан использовать new char[].
Строки это строки. Они никак не были "заточены" под коридоры и название оружия. Ходили слухи, что там была какая-то магия и их даже можно было использовать для имен собачек, кошечек и утконосов.
Да, да, классы в LISP 60-х годов. У которых почти иногда никогда редко не меняется имя в рантайме.
Или это мы в C++ программе постоянно посимвольно сравниваем имен классов и переменных? И почти иногда всегда меняем в рантайме... Магия!
в образовательных целях прочитать сгенерированную LLM статью с кучей ляпов и фактических ошибок?
Читать просто невозможно. ИИ нагенерировал главу для учебника по биологии с каким-то бесконечным количеством грубейших ошибок. В области C и C++, разумеется.
Какой волк, какой счетчик овец? Это техническая статья или постмодернистские галлюцинации?
Во-первых, нет никакой магии.
Во-вторых, фиксированные массивы не живут на стеке. Они вообще не живут. Их расположение определяется местом, где они определены и это далеко не всегда стек.
Типичный LLM ход.
Весь этот бред разбирать не вижу никакого смысла. Это просто мусор.
много букв и все ниочем
вне зависимости от операционной системы, схема в большинстве сценариев должна быть плюс минус одинаковая -- поток уходит в ОС с ожиданием набора различных событий (например, появление данных на сокете)
и одно из этих событий -- запрос извне на завершение потока
все, не надо ничего выдумывать
Частно нейронки работают по довольно таки старым базам. Например, бесплатная версия ChatGPT это до сих пор база лета 24-го года. Поэтому о многих свершившихся событиях они пишут в будущем времени, мол ожидается, запланировано и т.д. Спалил на этом довольно много местных статей.
в 99% хороших мобильных игр сегодня это что-то портированное с ПК, которое, естественно, теряется в потоке донатных помоек
но такие игры есть, просто они не на виду
нехорошие три строчки настройки стандартного логгера превратились в двадцать хороших строчек настройки логгера внешнего
статьи тут нет, есть только какая-то замануха в дзен
а был ли смысл писать на Rust c таким количеством ассемблера и unsafe секций...
в процессорах, где микрокод был не обновляемый (типа первого "пня"), его можно "считать" визуальным способом
там где обновляемый -- очевидно нет. это как увидеть, что хранится в чипе оперативной памяти, просто визуального его разглядывая
очередное нагенерированное LLM ниочем
у всяких технологий есть свои плюсы и минусы, по другому не бывает
и выбор стека это всегда про их понимание и компромисс
перед тем, как куда-то инвестировать, надо быть уверенным, что это хорошая идея и учтены все риски
реальный опыт бесценен
написать PoC на Qt с возможностью протестировать любое количество одновременных потоков + эмуляция вещей типа потери пакетов -- ну неделя работы
выделенная отдельно строка-шаблон лучше, потому что
ее легче прочитать и понять
ее легче локализировать
не согласен.
в коммерческих продуктах есть люди, которые за этим следят. это бизнес.
ну так это нормально, язык не должен стоять на месте.
для обучения вполне подойдет версия 2.0 аж 20-ти летней давности (до нее не было дженериков)