Это копия, сохраненная 21 апреля 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.
Пожалуйста, пользуйтесь https://ideone.com/#, https://wandbox.org/ или https://pastebin.com/ для вставки кода, если он длиной больше нескольких строк или содержит [i] или ∗.
Что читать:
- Brian Kernighan, Dennis Ritchie "The C Programming Language": http://www.cypress.com/file/56651/download
- Stephen Prata "C Primer Plus, 6th Edition" (2014): относительно свежая, знает про C89/C99/C11, описывает различия, объемная (около тысячи страниц), годная, с вопросами, упражнениями и ответами. Читать после K&R или до.
- Zed A. Shaw "Learn C the Hard Way" (2015): годное пособие для гуманитариев для гуманитариев!
- Немного примеров хорошего стиля: http://www.oualline.com/books.free/style/index.html
- ООП, например: http://www.cs.rit.edu/~ats/books/ooc.pdf
- Стандарт ISO/IEC 9899:1999 (C99): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1256.pdf (драфт)
- Стандарт ISO/IEC 9899:2011 (C11): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf (драфт)
- Черновик стандарта ISO/IEC 9899:202x (C2x): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2385.pdf
- man/Dash/zealdocs
Чем компилировать:
- Очевидный GCC.
- clang: оче годно, батя рекомендует.
- Intel C++ Compiler: оптимизации, тысячи их.
- Visual Studio 2017 Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте.
- Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное.
- TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
Что еще почитать:
http://c-faq.com/
FAQ из comp.lang.c. Древний, но все еще актуален.
Samuel P. Harbison, Guy L. Steele Jr. "C: A Reference Manual, 5th Edition" (2002)
Ебаный пересказ стандартов C89 и C99 (включая стандартную библиотеку). Для не осиливающих стандарт в оригинале. Читать в качестве подготовки к собеседованиям (есть задачник с ответами) и для ознакомления с масштабами пиздеца перед написанием своего парсера/компилера.
Peter Van Der Linden "Expert C Programming. Deep C Secrets" (1994)
"Си: грязные истории". Смехуечки, немного объяснений, чем обусловлены особенности языка, всем известные подводные камни кто там ругал косяки в JS? у нас в сишечке их гораздо больше, просто они лучше спрятаны, немного байтоебли и непонятно откуда взявшаяся глава про старинные плюсы. Читать в качестве сказки на ночь (на пару вечеров хватит).
Richard M. Reese "Understanding and Using C Pointers. Core Techniques for Memory Management" (2013) - почитать, вкатиться в указатели.
Ben Klemens "21st Century C: C Tips from the New School" (2012)
Paul Deitel, Harvey Deitel "C for Programmers with an Introduction to C11" (2013)
Stephen G. Koch@n "Programming in C (3rd Edition или 4th Edition, если найдется)" (2014)
MISRA Ltd. "Guidelines for the Use of the C Language in Critical Systems" (2013)
Набор рекомендаций по написанию надежного кода на C (промышленный стандарт). Читать - однозначно, следовать - вдумчиво и без фанатизма. Также можно посмотреть https://www.securecoding.cert.org/confluence/display/c/SEI+CERT+C+Coding+Standard и http://web.archive.org/web/20190213011655/homepages.inf.ed.ac.uk/dts/pm/Papers/nasa-c-style.pdf
Еще более длинный список: http://www.iso-9899.info/wiki/Books#Learning_C
https://github.com/kozross/awesome-c
Онлайн-утилиты:
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов).
- http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Прошлые треды:
- №50: http://arhivach.ng/thread/502813/
- №51: http://arhivach.ng/thread/510484/
- №52: http://arhivach.ng/thread/529928/ >>1570501 (OP)
>>1592455 →
Всё же не стоит слушать советы маня-петухов линуксоидов, в который раз замечаю что если им что-то непонятно они начинают орать что это во всём винда виновата и нужно срочно ставить юникс.
>>1592449 →
Анон, выпили 11-ю строку с ++len, т.к. это лишнее прибавление индекса. Ибо ты в цикле последнее что делал это прибавлял индекс, а т.к. программа вышла из цикла то индекс не забитый, следовательно после цикла увеличивать ничего не нужно, а нужно сразу записывать '\0'.
624x352, 0:42
Токсичний линуксоид, ничего удивительного. Триггерится на окна и пытается всеми правдами и не правдами завлечь человека в болото пердолинга.
Видео хочет рассказать мне, что непердоля готов терпеть отвалившиеся полки, заедающие ящики, пердящий двигатель, лишь бы рампочка горела прямо сейчас.
Чего ты хочешь от сектантов, использующих технику по религиозным мотивам. Пока другие занимаются делами, эти философствуют и агитируют в секту, а кто не согласится становятся врагами, против которых воюют. Обычное бесполезное быдло с кухонной политикой вместо жизни.
Можете подсказать, как в вашем языке эта строчка переводится?
А, тебе на таком уровне. Я уже начал расписывать, что в кавычках схема, проценты это плейсхолдеры для переменных после кавычек, амперсанты берут адреса.
Да не, я с лабой ебусь, уже просто для сокращения времени в треды захожу для переводов. То на си, то на плюсах, то на питоне код похожий нашёл, а решить пока не могу задачу
Владимир Васильевич, это вы?
Си с классами, хуле.
Ого, оказывается шизоиды, которые вещали, что Си это ООП язык, были правы. А я над ними смеялся. Приношу свои извинения. Ведь со стандартом не поспоришь.
> make, cmake, configure и прочей подобной залупе
Если у тебя есть program.c, ты делаешь make program, а дальше происходит магия. Просто и не требует ничего читать. По CMake есть стандартная книга Mastering CMake, отвратительная настолько же, насколько отвратителен сам CMake. А configure - это просто скрипт, внутри там может быть что угодно, и делать оно может что угодно, но так-то man autoconf.
Что значит отвратителен? Симейк нужен генерить проекты визуал студии из пердоисходников. Вполне полезная вещь, правда применение ограниченное.
> Что значит отвратителен?
Ну это когда ты можешь cc file.c, и все работает, но CMake тебе говорит, что на самом деле у тебя компилятора нет, и ничего не работает, и вообще ты мудак, и иди нахуй. Мало того, что синтаксис CMake в принципе не предназначен для восприятия гуманоидами, так тебе еще постоянно приходится расставлять везде if-ы на случай, если у твоего юзера старый CMake. А уж если тебе вдруг понадобится добавить туда поддержку кастомного компилятора, ты серьезно задумаешься о поиске другой системы сборки.
А еще нужно обязательно проверить, есть ли у тебя в 2020 году stddef.h. И еще раз проверить. И в каждом проекте отдельно проверить, вдруг он куда-то делся!
Есть еще m4 и др. Конкретно мне нужно разобраться как добавить опции компиляции в чужой проект или скомпилировать другим компилятором или слинковать этот проект с другой версией либы.
Двачну. Хуже cmake'a могут быть только люди которые его используют. Эти пидорасы попросту не пишут как правильно собирать их дерьмо.
>не пишут как правильно собирать
Но системы сборки существуют как раз чтобы не думать как собирать, а оно собиралось само. Иначе какой смысл?
Но когда я открываю cmake чужого кода, где под 200 строчек, а в каждой из вложенных папок ещё cmake файлы, то я понимаю что никакой возможности в этом разобраться нету, и это сложнее любого си, си++ и ассемблера сразу.
Вот си++ проект чужой для пример.
В верхнем файлы 597 строк. Это Eigen3 и он, слава богу, работает. Но по какой-то причине в проекте есть cmake-файл для Eigen3, хотя этот самый Eigen3 не требует cmake-файла и работает просто есть заинклудить его файлы.
Там происходит ошибка из-за того, что CMAKE_CXX_FLAGS имеет какой-то не такое значение, причём ошибка происходит в глобальных файлах cmake (который в директориях cmake находятся), а не в тех, что есть в этом проекте. Эта ошибка связана с openmp. Там есть кастомная переменная, которая включает и выключает куду и openmp, но даже когда я отключаю через это переменную - оно всё-равно жалуется на openmp, хотя казалось бы оно даже не должно пытаться его использовать после этого.
Для использования openmp обычно достаточно прописать set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp"), обычно. Я пробовал указывать это в разнообразных файлах вместо того кода, что уже был, но но всё-равно не собирается, потому что оно получается некую переменную OpenMP_CXX_FLAGS и без неё не работает. Какое значение должно быть у этой переменной - никто не знает.
За 4 часа я так и не смог собрать эту штуку и мне видится это очень плохой и перегруженной системой сборки. Книги про cmake которая создаст цельное представление как с этим работать - я не нашёл, отдельные статьи рассказывают лишь про cmake-файлы на 10 строк, которые и так исходя из содержания понятно что делают и как написать, и когда ошибка происходит в каком-то _FPHSA_HANDLE_FAILURE_CONFIG_MODE, то это даже не гуглится. Комментариев в cmake-файлах тоже нет.
Не понял твое поведение. Проект один, значит должен быть cmake в корне, в ним и работаешь, остальные не должны тебя касаться. Если нет какой-то библиотеки, нужно её поставить, иначе ничего не соберется, очевидно. Но ты зачем-то лезешь внутрь и пытаешься проигнорировать отсутствие библиотеки. Неадекватное поведение.
Очередной дебиловкатывальщик из питона и джаваскрипта закукарекал. Фундаментальный дефект мозга, ведущий к необучаемости и как следствие непригодности для программирования на си.
>не должны тебя касаться
Корневой cmake загружает дочерние (через include, ExternalProject_Add и subdirs - вроде бы всё это ссылается на другие cmake-файлы), потому что там кастомные либы (помимо всяких eigen - для которых они cmake-файл за компанию, видимо, засунули) со своими cmake-файлами от тех же, кто сделал "корневой" проект. Я собирал по отдельности каждую из дочерних либ вместе с тестовым кодом использования, и собрались (после фиксов по типу вычищения лишних строк про openmp) все кроме одной с той же ошибкой.
Отсутствие какой библиотеки я пытаюсь проигнорировать? Внутрь лезу не я, а ide, которое говорит про ошибку вызванную кодом во внутренних cmake-файлах.
Да, наверное проблема простая и фиксить за пять минут - но я не вижу точку приложения сил, мне не понятно куда копать и что читать, чтобы понять логику работы этого.
>Корневой cmake загружает дочерние
Это не должно тебя касаться, это не твой проект, Cmake файлы уже написаны, не тобой, значит они уже работают, а ты лезешь и ломаешь. Повторяю: система сборки существует, чтобы само работало, не нужно туда лезть. твоя задача работать только с самой системой, НО НЕ С ПРОЕКТОМ, лишь указать на нужный компилятор и нужные библиотеки предоставить, а сборка происходит автоматически.
>Я собирал по отдельности каждую
Решил страдать херней? Твоё дело, но Cmake тут ни при чем. Твои проблемы от твоей больной головы.
>ide, которое говорит про ошибку вызванную кодом во внутренних cmake-файлах.
Какая иде? Это всё консольное добро.
>Это не должно тебя касаться, это не твой проект, Cmake файлы уже написаны, не тобой, значит они уже работают
Не работают.
В более простых проектах (проектах с более простое иерархией в cmake-файлах) я открываю верхний CMakeLists.txt через ide и программа компилируется. В этом случае не компилируется.
>а ты лезешь и ломаешь
Боковые библиотеки не собираются. Если поправить cmake файлы (заменив /openmp на -fopenmp и удалив некоторые другие строчки), то они начинают работать, что говорит о том, что cmake файл не исправен (по крайне мере со стороны моего компилятора и моей версии cmake). Всё что нужно, пофиксить последнюю библиотеку, которая отказывается собираться, и тогда весь проект заработает (я думаю).
>Это всё консольное добро.
Я ничего не могу сделать с файлом "Makefile". Никакого видимого аналога make ни в папке компилятора, ни в папке Cmake, ни в папке ide я не вижу - что и каким образом делает ide с make-файлом - я не знаю, и не знаю где об этом прочитать, хотя очень хотелось бы.
Ты ругаешь меня и говоришь что я делаю не правильно, но при этом не говоришь что нужно сделать и игнорируешь мою фразу, что я не понимаю что нужно сделать и куда копать, чтобы в этом разобраться. Угу, а то я не понял, что я делаю что-то не правильно.
>что говорит о том, что cmake файл не исправен (по крайне мере со стороны моего компилятора и моей версии cmake)
Отлично, и какой из этого вывод? Конечно лезть в файлы и править. Браво.
А поставить правильную версию на ум не приходило? Ту, для которой создан проект и на которой собран? Что это за паталогическое пердоленье - создавать себе проблемы на пустом месте и устраивать героическую неравную борьбу с ними?
>Ты ругаешь меня и говоришь что я делаю не правильно, но при этом не говоришь что нужно сделать и игнорируешь мою фразу, что я не понимаю что нужно сделать и куда копать
А как иначе? Я не могу знать что там у тебя, поэтому ничего сказать не могу. Тем более, с CMake давно имел дело и всё забыл. Но это всё не имеет значения, ведь вопрос не в том что тебе делать, а в том, почему ты страдаешь херней (выше пример), почему у тебя отсутствует фундаментальная способность к здравому смыслу и когерентному логическому мышлению? А еще, подозреваю, отсутствует базовая компьютерная грамотность. С этим всем помочь не могу тем более, такое вообще неизлечимо как правило.
Но вспомним о чем был разговор: >>595771
Я не осуждаю твои ебанутые фетиши, но не надо обвинять CMake в своих личных загонах.
> Что это за паталогическое пердоленье - создавать себе проблемы на пустом месте
Это про CMake. Вот у анона проблема в том, что -fopenmp - это из gcc/clang, а то самое /openmp, что там было - msvc. Если бы у CMake был нормальный синтаксис, нормальная документация, вменяемые опции - человек, который писал CMakeLists, не хардкодил бы ключик, а сделал бы это правильно.
Я поставил cmake 3.11, как и указано у них на сайте. Выдаёт ошибку на стадии разбора cmake файлов, то что он какую-то хуйню с openmp (OpenMP_CXX_FLAGS) не может найти не считая фикса /openmp. Хотя там mingw в списке поддерживаемых есть и это должно само работать без моего участия. Да, ещё как я упоминал выше, там есть переменная USE_OpenMP, которая по идее как раз нужна для включения и выключения OpenMP, но если её поставить в false, он всё-равно пытается загрузить openmp и падает с ошибками.
Почему ты упорно считаешь, что я глупее тех, кто написал подобный cmake, и то что в cmake-файле нет проблемы?
>А поставить правильную версию на ум не приходило?
Если проект написаный под cmake 3.11 не собирается на версии 3.15 - то это какая-то сомнительная фигня получается, потому что найти несколько либ под одну и ту же версию cmake будет проблематично. Зачем там тогда вообще идёт строчка cmake_minimum_required(VERSION 2.8), если оно настолько версиязависимо?
>Конечно лезть в файлы и править. Браво.
Почти поправил. Боковая либа не работала без фиксов и заработала с фиксами. Зачем нужна система сборки, если она собирает под одну платформу, один компилятор и одну версию?
Так покажи. Как стек ломал-то? Другому анону интересно. У тебя data хранило значение не в пределах памяти стека?
>Я поставил cmake 3.11, как и указано у них на сайте.
Ну вот опять. Какой в жопу сайт, если непосредственно в файле CMakeLists.txt, про который ты только что сам говорил, первой строчкой идет версия. Где связь между сайтом и исходниками вообще? Ты сайт компилируешь или файлы проекта?
Дальше не читал, надоело.
Херовая документация затрагивает в той или иной форме примерно 100% софта, так что винить в этом конкретно cmake довольно странно.
тоже мимо
Да это очевидный пиздец.
1. CMake - полноценный язык программирования. Его скрипты - неоднородная процедурная портянка, в которой даже автор разобраться не может.
2. Нахуя он генерирует проект msvc (когда студии может не быть вообще), make-файлы и прочее говно вместо того, чтобы собирать самому? Всё равно лишняя зависимость.
Вместо CMakeLists.txt можно прикладывать экзешник, который сам всё соберёт. Никакой разницы.
Вот было бы для сборки что-нибудь декларативное и удобное, как хотя бы мавен. На автоматическое разрешение зависимостей я и не надеюсь даже.
Я не думаю, что кто-то тут считает, что cmake охуительно хороший, это просто артефакт своего времени, как какой-нибудь ed. Такой "весёлый" из-за кросплатформенности между досом и юниксом, так что экзешник ты не приложишь, или на твоём любимом сорте линукса не заработает.
>Нахуя он генерирует проект
Потому что в этом его задача, это автобилдер, а не компилятор. Какие ещё есть интерфейсы для общения с компиляторами?
> артефакт своего времени
Если бы. Его используют вовсю, и подыхать он не собирается.
> не заработает
А проект для говновижуалки не заработает, если вижуалка не установлена. Ну окей, пусть будет не экзешник, а скрипт на питоне. Всё равно придётся что-то доустанавливать.
> автобилдер, а не компилятор
Ну так и make - это не компилятор.
>Если бы. Его используют вовсю, и подыхать он не собирается.
Естественно. Люди крайне не хотят изучать что-то новое, даже если оно лучше подходит под их задачи. Установить и разобраться с линуксом? Нет, они уже привыкли к виндоусу и ни за что с него не слезут. Лучше сидеть и неделю за неделей рационализировать свой выбор, чем это время потратить на изучение нового. И так на каждом уровне: vim, systemd, emacs, wayland.
А так даавно уже есть более современные и вменяемые автобилдеры, тот же Meson, который как раз использует
>скрипт на питоне
>Ну так и make - это не компилятор.
Так make и не автобилдер. Make — это рецепт, а cmake это генератор рецептов, в зависимости от того, сковородка у тебя есть, или духовка, или кухонный комбайн.
> Люди крайне не хотят изучать что-то новое
В более хипстерских языках изучают охотнее. Часто меняют системы сборки, переходят с одних "устоявшихся" фреймворков на другие и т.д.
> Meson
Хм, надо глянуть.
> Make — это рецепт, а cmake это генератор рецептов
Наверное, я хочу что-то среднее. Чтобы оно само на разных системах налету генерировало и сразу же исполняло рецепты.
>В более хипстерских языках изучают охотнее. Часто меняют системы сборки, переходят с одних "устоявшихся" фреймворков на другие и т.д.
Давай так. Ты сам сидишь на винде и являешься частью абсолютно этой же проблемы. Разбирись в себе, и узнаешь, почему эти ребята не хотят слезать с cmake.
>Чтобы оно само на разных системах налету генерировало и сразу же исполняло рецепты.
Оно так и делает? Когда оно у тебя останавливается?
Ну я почему то половину проектов не могу собрать. А все из-за того, что система настолько гнилая, что самим разрабам впадлу потратить 5 минут и написать нормальные правила и документацию по сборке.
>> Люди крайне не хотят изучать что-то новое
>Наверное, я хочу что-то среднее. Чтобы оно само на разных системах налету генерировало и сразу же исполняло рецепты.
Ну и почему ты не хочешь ничего изучать, кроме единственной волшебной кнопки на все случаи жизни? Даже не начал ничего изучать, а уже слился. Может стоит признать собственную несостоятельность и съебать в закат?
>>596330
А как оно исполнит? На линуксе могу поверить, но не на винде. CMake работает в обычной консоли, а для сборки сгенеренного проекта нужно запускать консоль студии, а их еще две, в зависимости от разрядности. А если ты долбоеб захочешь открыть в IDE и там тыкать мышкой?
>А как оно исполнит? На линуксе могу поверить, но не на винде.
В винде одни программы не умеют вызывать другие, по твоему мнению, или что?
>А если ты долбоеб захочешь открыть в IDE и там тыкать мышкой?
Если ты хочешь влезть в середину пайплайна и потыкать там что-то, то естественно пайплайн нужно остановить. Так же как, например, с gcc -c. Для этого cmake тоже пригоден.
> не хочешь ничего изучать, кроме единственной волшебной кнопки на все случаи жизни
Да, я хочу волшебную кнопку. Почему вместо решения задач программы, которую я пишу, я должен возиться с однотипными проблемами сборки, которые до меня уже тысячи раз решали и продолжают решать вместо автоматизации этого процесса, как в других языках? Давно уже изобрели более удобные инструменты, но почему-то принято их не использовать, а страдать.
В ебучем мавене достаточно написать пять однотипным строчек, чтобы всё само скачалось и импортировалось. Здесь же приходится ебаться с каждой первой библиотекой.
Впрочем, не исключаю, что это всё с непривычки. Больших/средних проектов на C/C++ я не писал.
>Да, я хочу волшебную кнопку.
Вот и авторы проектов cmake считают точно так же. Тяпнул, ляпнул, заработало? Готово, лучше они пойдут решать задачи программы, которую пишут.
Неее, с cmake так точно не будет. Не "тяпнул ляпнул", я будешь долго сидеть и копаться. Когда наконец заработает, никто не гарантирует, что скоро сломается. И до написания собственно кода так и не дойдёт.
Ну, главное у них заработало. Будут они ещё возиться с однотипными проблемами сборки!
> А как же Makefile?
А у make implicit rules есть, если тебе просто спроситьсобрать. Makefile - это когда тебе что-то посложнее нужно.
Ну вот, анон спрашивал про искусство обмазывания всякими мейками, очевидно имелись ввиду мейкфайлы, а не шорткат cc -o $1 $1.c
Придумал такой пример:
int b = 10;
if (a || ++b) {
printf("%d\n", ++b);
}
Правильно ли я понимаю, что в таком случае мы имеем undefined behavior? Так как изменение переменной b происходит дважды между двумя sequence points?
> изменение переменной b происходит дважды между двумя sequence points?
Нет тут такого. А вот если бы у тебя было:
++b + ++b
То да.
Точно? А можно какой-то пруф, пожалуйста?
А то вот все, что я нашел:
1. В конце каждого полного выражения(Глава Стандарта 1.9/16). Обычно они помечены точкой с запятой ;
2. В точке вызова функции (1.9/17). Но после вычисления всех аргументов. Это и для inline функций в том числе.
3. При возвращении из функции. (1.9/17) Есть точка следования сразу после возврата функции, перед тем как любой другой код из вызвавшей функции начал выполняться.
4. (1.9/18) После первого выражения (здесь оно называется 'a') в следующих конструкциях:
a || b
a && b
a , b
a ? b : c
Сори, что это для плюсов
> At the end of a full expression. This category includes expression statements (such as the assignment a=b;), return statements, the controlling expressions of if, switch, while, or do-while statements, and all three expressions in a for statement.
В древнем стандарте был неявный инт, его можно было не писать.
С с99 сконпелирует, с с11 выдаст Wimplict но тоже сконпелирует. Только в этом ворнинге даже смысла нет, ибо конпелятор не даст выстрелить в систему и ретерны сам подставит. Смысл исключительно стилистический
не нормально такую хуйню спрашивать
Я тебе открою страшную тайну: прорешивание упражнений из книжек прокачивает тебя в умении решать упражнения из книжек. Прокачивают ли они тебя как программиста, науке до сих пор не известно.
Сикп уже полностью прорешал, ковбой? В нвидию устроился?
ну у страуструпа там 1000+ страниц.
ага, только есть одно НО, без синтаксиса ты обосрёшься. его всё равно учить надо, элементарно книгу от создателя по языку нужно пройти чтобы начать на нём кодить.
https://pastebin.com/LqTwwxeZ
Когда грузится с существующего файла, у нее то во время load
>corrupted size vs. prev_size
то во время save
>sysmalloc: Assertion `(old_top == initial_top (av) && old_size == 0) || ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && ((unsigned long) old_end & (pagesize - 1)) == 0)' failed
це ж бля якась пiзда...
Надо заметить, это происходит, когда округленный размер для аллокации вычисляется типа так size+-size%0x40 . Разувериваться в безопасности этого божественного трюка я, однако, решительно отказываюсь.
Сложно сказать. Там рассказывается вообще всё, но на практике большую часть будешь использовать редко. Что действительно можно сказать, так это то, что прям задрачивать теорию не нужно, лучше потратить это время на написание своих проектов. Да и нормальные люди быстрее эту книгу читают, так что вдруг в твоём случае будет всё не так плохо, как у меня.
Я и не задрачиваю теорию, я просто стараюсь решать все задачи которые представлены в книге. Ну лишними эти знания не будут в любом случае, может быть на практике то и не будешь использовать на знать полезно для более детального понимания, мало ли когда пригодится.
Не в чтении проблема, а проблема в заданиях. Прочитал и тебе 4 задания выкатили и ты их 3 дня решаешь. Ну я, правда решаю на совесть, а не на отъебись чтобы идеально было. Не знаю я мне кажется страуструпа я тоже наверное года 2 буду изучать.
>Ну я, правда решаю на совесть, а не на отъебись чтобы идеально было.
Ты так можешь к плохому приучиться, до хорошего не дочитав.
о так мы ровесники, мне 22 исполняется через, месяц. А что так? Голый Си же никому не нужен сейчас, я сам в Си вкатываюсь, только чтобы в плюсы вкатываться проще было. У меня цель на С++ кодить. Ради этого я прочитал книгу которая знакомила с основами погромирования на базе питона, прочитал вводную книжку о радиоэлектронике. Сейчас вот СИ пройду, наконец до С++ дотяну.
На него просто подготовиться надо хорошо.
Да я прост в другие языки перекатился, где легче найти работу. Целеустремлённости не хватило довести до победного.
На плюсах даже прочитал книжку по Qt + мануалы по парочке других либ. Даже писал что-то. Сейчас иногда пишу ннбольшие проекты для себя, когда есть желание и свободное время.
В веб небось перекатился? У меня была одна попытка вкатиться в веб, но он какой-то пресный и бездушный. А вот С\С++ для души, неудиветильно, что ты даже сейчас на них продолжаешь кодить.
Бекенд, жаба.
>А вот С\С++ для души, неудиветильно, что ты даже сейчас на них продолжаешь кодить.
Пожалуй, так и есть.
мимо 21 лвл, вкатываюсь в функционалОЧКУ и продолжаю говнокодить на Сях для души
Когда создаёшь указатель, ты пишешь тип на который он ссылается. Компилятор знает размер этого типа и оперирует данными по адресу в указателе в соответствии с этим типом и его размером.
Какое отношение упражнения имеют к синтаксису? Learn You Haskell for a Great Good, например, вообще без упражнений, а в ней не только синтаксис, но и всякие концепции вроде аппликативных функторов и моноидов описаны. А уж Си в разы проще, по-крайней мере если брать язык сам по себе, без предметной области в виде системного программирования и т.д.
Я же не говорю, что разбираться вообще не надо, просто глупо решать все упражнения подряд. Нужно оценивать упражнения исходя из того, что они могут тебе дать и какой цели ты хочешь добиться в процессе обучения.
В хуевых книгах в упражнениях даются новые знания. То есть смотришь упражнение, видишь - хуита скучная, а потом оказывается, что в решении там важный пункт главы, но если ты не решал упражнение, то ты не заглядывал в решение , и поэтому нихуя не узнал. Насколько я помню, K&R хорошая книга, а вот Кнут или SICP - хуевые.
Если в книге нет каких-то важных пунктов, либо нет сносок типа "эта тема отдельно заняла бы целую главу, поэтому загляните в такой-то источник, если считаете необходимым", то это хуевая книга и ее читать не нужно.
в том что если тупо читать не делать упражнений это в одно ухо влетает в другое вылетает. благодаря упражнениям ты на практике видишь как это всё работает.
>в том что если тупо читать не делать упражнений это в одно ухо влетает в другое вылетает.
Это называется ADHD, твоя мамка мало витамина D ела
Сишники вопрос на повестке дня. Что не так с С под окнами и почему все говорят что на С надо кодить только с UNIX подобных систем
Причем тут ADHD?
Заебали. В Си все ок, на Си надо кодить. ОС - дело десятое.
ну это примерно как прийдти в автошколу, инструктор сядет за руль поездит, расскажет тебе как всё переключается и скажет "ну всё давай иди, через неделю в гаи на экзамен" примерно тоже самое читать теорию и не делать никаких задач.
Просто создатель СИшки был ярым фанатом пердолей, поэтому это мнение даже в своей книжке пропагандировал что он под unix заточен и всё здесь на примерах unix системы. Нормально под окнами кодиться, на них. К тому же сам microsoft активно двигает эти C\C++
на что ты намекаешь? когда я говорил что майкрософт сишки двигает, я не имел ввиду что их разработали они, а то что они как монополисты на рынке создают основные продукты на нём. и в виде тех же вакансий.
Просто вместе с тобой поражаюсь, как это
>создатель СИшки
> своей книжке пропагандировал что он под unix заточен
вместо того, чтобы просто и ясно сказать, что
>Нормально под окнами кодиться
за 14 лет до их создания.
а ну понял. ну я особо там не ебу когда что создано было, кек ёбаный. в конце концов я книгу от 2014-го года вроде как читал или от 2011-го не важно, можно было написать что окнам инормально кодится.
>от 2014-го года вроде как читал или от 2011-го не важно
Создатель С в 2011 уже умер.
Многовато ты "не особо там ебёшь" для обладателя такого сильного мнения, я тебе скажу. Какую-то книгу, непонятно чьего авторства, неизвестно какого года прочитал, и она тебе всё объяснила. Книга точно по С была, а не по эзотерике?
>Что не так с С под окнами
С учетом того, что Windows API исключительно сишный, это очень странное утверждение
> Windows API исключительно сишный
Уже давно не исключительно. Есть крестоапи местами уже (те же HTTP, или GDI+), есть COM, который тоже по идее на крестах, хотя и можно дергать из Си. И, наконец, есть множество managed интерфейсов без native эквивалентов.
>То, что на С++ - это врапперы.
На голом винапи еще во времена windows 3.1 забили писать, слишком геморно, по крайней мере что касается гуи-интерфейсов, для которых сделали библиотеки на классах. Да что винда, сам язык без классов не имеет смысла. Тот же банальный std::string, как ты без строк собрался программировать, клоун. Разве что студентик олимпиадник с лабами уровня хеллоуворлд.
тише, дружище. Тут половина треда это дети из школы 21, которые строк сложнее ASCII не видели, ты на себя только помойное ведро сейчас навлечешь рассказывая им о реальном мире, где даже на микрухе эмулируют ООП.
Мастер, научи...
А переведите, пожалуйста, все задачи с пика. Я вообще ебанусь с этим ёбаным инглишом я не понимаю нахуй что они хотят.
я уже нашёл, спасибо.
В случае ++i оно добавляет единицу и возвращает это значение.
В случае i++ оно возвращает переменную и добавляет единицу. Тут ещё якобы временная переменная может появиться в каких-то случаях. Смотри префиксный и постфиксный инкремент.
Можешь просто использовать только первый, он гарантированно не хуже второго.
Всё же посмотри что-то про "префиксный и постфиксный инкремент", я очень грубо описал - подумал что ты просто названия не знаешь.
понял. щас гляну, спасибо ещё раз, анчоус.
А ты не можешь объяснить зачем у него в коде константа COLS?
И что значит "tab stops" у него в задании. Что это за остановки табуляров такие?
прочитал, спасибо.
>>599359
https://codereview.stackexchange.com/questions/124866/kr-1-20-solution ссылка отклеилась. анон, скажи, пожалуйста, зачем ему константа cols и что такое tabs stops?
> GDI+ тоже
Ты опять выходишь на связь? Уже написал для нас пример работы с Flat GDI+ API на Си?
>>598999
> На голом винапи еще во времена windows 3.1 забили писать
Куча софта написана на голом винапи. Вон, например, новая миранда недавно зарелизилась, лол.
> даже на микрухе эмулируют ООП
ООП != кресты. ООП - это про объекты, на сишке точно так же пишут в ООП-стиле, передавая указатели на структурки в соответствующие им функции, потому что это единственный разумный подход в больших проектах.
Ну типа в консоле ширина табуляра расчитывается формуле
8 - ("number of symbols in a string" % 8)
COLS у него это тот самый tabs stops по-русски говоря шаг табуляра, каждые 8 символов. То есть табуляр идёт не от последнего введённого символа, а он идёт как по линейке.
Пример на пике 2.
Попробуй это в консоле, с запятой после hello и без неё и ты заметишь что ширина табуляра динамическая. То есть сама ширина табуляра она не фиксирована, а равна расстоянию которое осталось до tabs stop. Если осталось до него 3 символа, то 3 ём пробелам, если 5 то 5-ти пробелам.
Символ конца строки. Не путай с '\n' который означает переход о на новую строку.
Нет, ты не понял, анон, я не про '0' говорил. а про 0 без кавычек, то есть не символ
Я знаю, что такое символ конца строки. Чем отличается '\0' от обычного нуля, который не символ? Зачем ввели '\0' (это же отдельная escape sequence (еще раз повторяю вопрос)), вместо того чтобы просто писать нуль (не символьный нуль)?
Ну это разве реалистично? Ты так стал бы писать? Чтобы строки в таком виде не раскладывать и ввели. Так-то можно и '\n' на 10 в ASСII заменить.
> Зачем ввели '\0' (это же отдельная escape sequence
Чтобы делать "foo\0bar\0abc\0def\0\0", например. В форме символьной константы не отличается ничем, но в крестах, например, '\0' это char, а 0 это int. В сишке оба инты.
Понял, сяп.
>В сишке оба инты.
А это точно? '\0' - это интовая константа/литерал?
То есть при char x = '\0' происходит неявное преобразование из signed char в signed int?
Алсо если '\0' - это заложенная стандартом СИ (ВЕРНО?) escape sequence, то почему я не вижу ее в этой таблице?
https://en.wikipedia.org/wiki/Escape_sequences_in_C
>неявное преобразование из signed char в signed int?
Опечатался. Имел в виду, из signed int в signed char
быстрофикс
>>599546
>>599548
Вам тоже спасибо, анончики. Но я хотел услышать, чем именно отличается 0 от '\0'. (я думал, мб, '\0' является char-константой, а не интом). И хотел понять, является ли '\0' стандартизированной escape sequence. И эти вопросы все еще открыты. Сори, если я изначально по-еблански спрашивал, и вы меня не совсем так поняли
>почему я не вижу ее в этой таблице?
С глазамы проблемы, похоже. Посмотри ещё раз внимательней на числовые последовательности в той таблице. Её ещё можно записать как \x0 или \u0000 например.
'\0' является частью набора символов. В мультьтибайтовом кодировании он может быть представлен в том числе и несколькими байтами, если структура жёсткая (например, строго три байта на символ). Но обратное запрещено (нельзя использовать '\0' для чего-то другого).
http://www.open-std.org/jtc1/sc22/wg14/www/C99RationaleV5.10.pdf
5.2.1.2
>The null character ('\0') may not be used as part of a multibyte encoding, except for the one-byte null character itself. This allows existing functions which manipulate strings to work transparently with multibyte sequences.
Запрет тут проговорен явно, а возможное мультибайтовое представление, это уже мой вывод.
>>599614
>The byte whose numerical value is given by ...nnn interpreted as an ...al number
Так какой еще the byte? В стандарте регламентируется соответствие \nnn определенному byte? Что это за byte? Откуда он берет соответствие?
И я все еще не увидел ничего про однозначное соответствие '\0' нулю
Спасибо. Все же выходит, что '\0' это это однозначно one-byte null character itself, однако соответствие этого null character конкретному числу зависит от применяемой кодировки, так? То есть может оказаться, что '\0' == 116?
\0 - это в восьмеричной (octal) системе 0.
\1 -> 1
\2 -> 2
...
\7 -> 7
Байт, соответсвенно 00000000, 00000001, 00000010, ... 00000111.
>То есть может оказаться, что '\0' == 116?
Не запрещено, насколько я понимаю. Строчки обязательно должны заканчиваться чем-то, что представляется '\0'. Если это будет (long long) 116, то ничего страшного, но нельзя использовать (int) 0 для других целей, например, обозначать так 'a'.
Действительно. А ещё система может быть не windows. Зачем вообще это в стандарте языка программирования? Пусть пердоли сами разбираются!
>Байт, соответсвенно 00000000, 00000001, 00000010, ... 00000111
Понял. Значит, в однобайтовой кодировке мы составляем байт с помощью \nnn value (в данном случае octal).
То есть в таком коде:
char x = '\0';
Работает следующим образом:
1) '\0' - данная escape sequence составляет байт 00000000
А дальше?
> А ещё система может быть не windows
Как ни пиши, что-нибудь хоть сколько-то большое без плясок даже на разных версиях одной ОС сходу не заработает.
>>599696
Меньше байта всё равно не будет. Например, булев тип тоже занимает аж целый байт, и 7 битов из 8 расходуются зря. А с учётом алигнмента ещё больше.
ну я и не заявляю что байт может быть меньше 8 бит. просто это к тому же не все биты используются.
а что из себя представляет мусор? ну вот допустим мусор в массиве в си где анон вначале треда горел что ему не объяснили. что есть мусор в символе?
в массиве, не в символе. пофиксил себя.
>но нельзя использовать (int) 0 для других целей, например, обозначать так 'a'.
А вот про это где сказано?
Регламентируется стандартом?
Не нашёл постов про мусор. Наверное, речь про неинициализированные данные, когда ты получил в своё пользование память, но ещё ничего ей не присвоил, но пытаешься её читать. Там может оказаться что угодно, и по стандарту такое чтение - undefined behavior.
спасибо, понял.
>The null character ('\0') may not be used as part of a multibyte encoding, except for the one-byte null character itself
Эта?
Но тут ведь не говорится, что кодировка не может в (int) 0 кодировать какой-либо символ, вроде того же 'a'.
Здесь просто говорится, что '\0' не может быть частью составленного из нескольких байт символа (в мультибайтовых кодировках).
Или я уже совсем ебнулся?
Попробую перефразировать:
Исходя из цитаты, я не вижу запрета на использование (int) 0, в однобайтовых кодировках для кодирования каких-либо символов
> стандарт:
> A byte with all bits set to 0, called the null character, shall exist in the basic execution character set
О чем вы вообще?
execution character set - это другое.
Я спрашиваю о том, допускается ли создание кодировок, в которых null character-ом (нулевым байтом) будет кодироваться какой-нибудь символ. Например 'a'.
> это другое
Нет. Execution character set - это то самое, с чем работает твой код в рантайме. А source character set - это о тексте программы, который компилятор читает из .c файла. Все важное (читай: строковые литералы) конвертируется в execution character set практически сразу же.
Понял.
Но ведь
>shall exist
не означает shall represent a line terminator или вроде того
Имею в виду, где регламентируется то, что все кодировки в качестве байта/набора байтов, где биты установлены в 0, должны представлять собой признак окончания строки (не могут являться каким-либо другим символом, вроде 'z')?
Что мне мешает сделать кодировку, где null-character будет кодировать цифру '8'? Ничего ведь, верно? А где в стандарте Си говорится о том, что такую кодировку для программ на Си использовать нельзя?
Ну правда. Язык элементарен.
Но как только пытаешься влезть в исходники nginx или даже sqlite, мозг начинает плавиться и вытекать.
Все, кто не использует тайпдефы для сложных типов - пидарасы. И пишут они говнокод.
Ну смотри, первое действие выполняется в скобках, значит лезем в самые глубокие.
Там у нас две на одном уровне
(✭foo) и (void )
значит слева направо:
(✭foo) - звёздочка, значит указатель, указатель на foo. Что такое foo, ещё не знаем. Смотрим дальше.
(void ) - тип в скобочках после названи, значит это аргумент, а foo, получается, функция.
(✭foo)(void ) - указатель на функцию foo с аргументом void
Поехали дальше, следующие скобки:
(✭(✭foo)(void )) означает, что эта функция возвращает указатель, указатель на что?
int ✭ [3]
Указатель на массив из трёх интов.
Итого:
int (✭(✭foo)(void ))[3] - указатель на функцию foo от void, возвращающую указатель на массив из трёх интов. Без задней мысли :3
>>599858
А тайпдефы ты как разбирать будешь, ммм?
Прочитаю один раз комментарий к тайпдефу вместо того, чтобы парсить эту хуиту каждый раз.
А что значит "указатель на массив из трех интов"?
Указатель может быть только на тип инт. То есть на нулевой элемент в массиве.
Так что ты немного проебался, походу. Там функция return'ит массив из 3х указателей на int
Указатель может быть на другой указатель.
>Указатель может быть только на тип инт.
Указатель может быть на что угодно. Более того, ты по нему даже можешь размер объекта узнать, так, например, память для многомерных массмвом выделяют.
>Там функция return'ит массив из 3х указателей на int
Тогда было бы вот так
int ✭(✭foo)(void )[3]
А какой смысл в первом случае? Там, где "указатель на массив из трех интов"? У нас типа в той строке инициализируется пустой массив из 3-х интов и ретернится указатель на него? Так? (Если опустить функцию)
Я не очень понимаю, какой смысл ты ищешь. Я просто показал, что так можно. Зачем это вообще отдельный разговор, можешь обсудить с аноном выше, у которого во всем тайпдефам комментарии есть.
Понял, прикольно. И полезно. Первый раз такое вижу. А за счет чего вообще меняется смысл при заключении указателя в скобки? То есть к каким вещам мне вообще нужно было бы обращаться, чтобы понять, что int (звездочка foo)[3];
Объявляет указатель foo на безымяный инт из 3-х элементов? Я не понимаю, как все это связывается так.
Или ты про терминал? Тогда fish
> Но обратное запрещено (нельзя использовать '\0' для чего-то другого).
Утютю. '\0' это лишь нулевой байт типа char но на типы си похуй, там всё - числа. Всё состоит из байтов, используй как угодно.
> Но я хотел услышать, чем именно отличается 0 от '\0'.
char c = 0
от
char c = '\0'
отличается ничем
А про что? Если я не протупил, разговор был про бред, . Кодировки не включают в себя нулевой символ, кроме единственного - терминатора. Т.е. \0 не используется нигде, кроме конца, остальные строки пишутся без нулей, любые.
>>600029
О том и речь. 0 это int, а не char. Разница как бы есть, хотя конечно язык всё равно преобразует, сократит или растянет если надо.
>ясно
У дебилизма есть и свои плюсы, удобно определять. Все дебилы как боты по одному шаблону. Пяток регексов и посты автоматически подсвечиваются.
Зарепортил.
Двачую. Тот же самый код с использованием using/typedef и нормальными кастами выглядит в разы понятней.
Хочу вкатиться в разработку прошивок для умных девайсов и прочей имбэдщины (не спрашивайте почему я такой ебанутый, просто люблю лоу лвл, и к тому же, у меня в стране это востребовано, поэтому голодным не должен остаться).
Что посоветуете почитать? Насколько нужно быть матерым в железе? А то я из мира софта, а о железе знаю только названия нескольких интерфейсов вроже uart, spi, i2c, jtag... Я понимаю, что разработка прошивок - это 85% времени втыкания в datasheet девайса, под который пишется прошивка, но тем не менее, хочу какой-нибудь мало-мальски структурированный источник информации по сабжу. Ну и имеются в виду прошивки, которые крутятся на борде , процессором, а не без оного (слышал, что есть разница, ибо там, где не проца, все пишется на fpga или верилоге, могу ошибаться).
О себе вкратце - студентота, знаю Си, кресты, немного внутренности Линукса (и вообще Линукс няшка, да, я линуксоид), асм х86 и немного знаю асм ARM, имею опыт в базовом реверс-инжиниринге. Ну и сети, алгоритмы, структуры данных, офк, тоже.
После энного кол-ва опыта обязательно захочу вкатиться в безопасность прошивок (реверсинг и эксплуатация). Но без опыта в разработке оных, я полагаю, смысла сразу прыгать в инфосек сей отрасли не имеет смысла (или я ошибаюсь?), поэтому и прошу о помощи.
Дай наука здоровья всем, кто ответит.
У тебя ведь тут получились два анонимных массива на фрейме стека размерностью 72 и 576 байт, соответственно, к которым никак не обратиться, а также два сложных составных типа int (звездочка) [][], в которых указатели указывают на последовательность байтов на куче размерностью 72 и 576, соответственно. Верно?
Я к тому, что ты к своим массивам никак не обратишься, ибо указатели переопределил.
Ну то есть, несмотря на то, что escape sequence '\0' составляет нулевой один байт, компилятор все равно формирует из этого байта int, а потом неявно преобразовывает к char в таком коде?
char x = '\0';
Я нигде не создавал массивы на фрейме стека. Так же как
int (*foo)(float a, double b)
не является функцией, так и
int (звездочка) [][]
не является массивом.
Я еще не дошел до подобных сложных составных типов, поэтому и задаю такие вопросы.
>int (звездочка) [][]
не является массивом.
Тогда почему в таком коде не выдает segmentation fault?
char ('звездочка'arr_ptr)[6];
'звездочка'arr_ptr[0] = 'x';
'звездочка'arr_ptr[1] = 'y';
Бля, какая же сишка охуенная. Простая и понятная, ничего лишнего, но при этом такая мощная. Обожаю сишку.
А, ну у меня clang онлайн почему-то не ругался.
Спасибо за скрин.
Зачем тогда указывать размерность массива при объявлении указателя на него? (Для того, что ты показывал на примере выше с sizeof?) Это ведь по сути указатель на указатель. На конструкцию char ('звездочка'arr_ptr)[]; не ругается же
>(Для того, что ты показывал на примере выше с sizeof?)
Имел в виду, объявляем размерность массива, на который указывает указатель, чтобы могли такие фичи вытворять с определением размера по сути даже неинициализированного массива в памяти (тупо по описанию)?
>На конструкцию char ('звездочка'arr_ptr)[]; не ругается же
Естественно не ругается, это просто неинициализированный указатель. На int ✭ ptr; тоже ругаться не будет.
>>601089
>определением размера по сути даже неинициализированного массива в памяти (тупо по описанию)
Со структурами же так постоянно делаешь, почему с массивами не делать.
https://pastebin.com/g1shMe1J
Делал упражнение 1-20 из книги k&r. Что скажете? Хороший он? не говнокод? Как у него с оптимизацией? Я старался чтобы программа делала как можно действий при выполнении.
вроде неплохо, покрайней мере с условиями if else ты хорошо дружишь, большинство ньюфань все через if прописывают.
я не подъёбывал, мне действительно кажется что у него с условиями всё ок. если видишь у него дерьмо в коде напиши где.
>это просто неинициализированный указатель
Угу, такой же неинициализированный как и char ('звездочка'arr_ptr)[6];
>Со структурами же так постоянно делаешь, почему с массивами не делать.
Хм, кстати, да. Логично. Что-то не подумал об этом.
Еще такой вопрос касательно дискасса: а как именно sizeof высчитывает кол-во памяти, (потенциально) используемой тем или иным типом? Возьмем те же случаи с размерностью описанной структуры или размерностью неинициализированного массива. sizeof просто смотрит из каких простых типов состоит данный составной сложный тип, через компилятор получает инфу от ОС о размерности простых типов данных на конкретной машине, и перемножает, складывает, чтобы получить размерность составного типа? Или это работает совсем иначе?
И еще: а чем конкретно отличается char 'две звездочки'ptr и char ('звездочка') arr_ptr ? В первом случае у нас указатель на указатель на char. А во втором - указатель на массив char'oв. Но ведь массив char'ов состоит из указателя который указывает на нулевой байт набора - то есть то же самое, а именно указатель на указатель на char, нет? И да, я вижу, что компилятор мне выдает ворнинг при попытке ptr = arr_ptr;, мол, это разные типы, но почему? Хочу прояснить тонкости
>и char ('звездочка') arr_ptr
char ('звездочка') arr_ptr[]
быстрофикс, забыл квадратные скобки добавить
>Угу, такой же неинициализированный как и char ('звездочка'arr_ptr)[6];
Да. Проблема-то там не в создании указателя, а в том, что ты неинициализированной переменной в 'звездочка'arr_ptr[0] пытаешься 'x' присвоить. А его некуда присваивать, указатель неинициализированный, он никуда не указывает.
>Хочу прояснить тонкости
Читай книжки. Объяснять, конечно, полезно, но мне столько печатать лень.
>оптимизацию кода
Я бы тогда нагенерировал все возможные количества пробелов заранее и выбирал среди них через switch, а не цикл
for (int i = 0; i < TABSTOP - (count % TABSTOP); ++i)
крутил.
Ну и заменять одну '\n' на другую в
if (c == '\n') putchar('\n');
довольно странно. Как в известном индусском яваскрипте:
if a==5 return 5;
if a==6 return 6;
и т.д.
> нагенерировал все возможные количества пробелов заранее
printf("%*s", num, "") или даже "........" + [8 - num].
Да, или так. Я просто думал про более сложные случаи, когда строчки разные С массивом мне нравится больше всего.
>Да. Проблема-то там не в создании указателя, а в том, что ты неинициализированной переменной в 'звездочка'arr_ptr[0] пытаешься 'x' присвоить.
Я это понимаю. Изначально пытался присвоить какие-то значения, потому что не понимал, что под массив в той конструкции не выделяется память. Ну то есть семантика самого оператора была не ясна. Сейчас-то я уже понял суть.
>указатель неинициализированный, он никуда не указывает.
Если говорить корректно, то он указывает в произвольный (или несуществующий) участок памяти (адрес), ибо память, которая выделяется для указателя при объявлении этого самого указателя, содержит мусор. Но ты это итак, конечно, знаешь. Просто не хочу каких-то недосказанностей. Думаю, когда мы говорим в частности о Си, то особенно важна точность формулировок.
>Читай книжки. Объяснять, конечно, полезно, но мне столько печатать лень.
Ну плез, плез, плез, анончик. Очень тяжело выцепить прошаристых людей. Особенно в таких штуках. Серьезно. И не обязательно сейчас катать стену текста, если там много. Можешь ответить по возможности, например, завтра вечером. Когда я начинаю углубляться в это, то одна прочитанная вкладка материала порождает две-три непрочитанных, ибо вопросов больше и больше.
Кстати, а какие книжки читать, к примеру? Что посоветуешь?
>Очень тяжело выцепить прошаристых людей.
А я не прошаристый. Я читал-то одного прату. Но мне понравился. Просто попадается что-то интересное, открываю стак оверфлоу, а там вот такие ответы
https://stackoverflow.com/questions/1247486/list-comprehension-vs-map/6407222#6407222
Или такие
https://keithschwarz.com/interesting/code/?dir=knuth-morris-pratt
Но это, конечно, не очень хороший способ систематические знания получать, книжки лучше, просто я нетерпеливый.
а потому что счётчик \n считает, а её считать нельзя. иначе программа будет некорректно пробелы считать.
Аноны, а зачем вам это древнее говно? Вы бы еще на турбобейсике кодить начали?
Ну серьезно- нахуя?
> Вы бы еще на турбобейсике кодить начали
C старше
> Аноны, а зачем вам это древнее говно
А что если не C?
От этого языка блевать не тянет, как от всяких модных питонов, похапэ и яв. Этот язык с душой, мне всё равно сколько ему и есть ли работа на нём, буду кодить на нём.
Этот язык символ того времени когда программист был ещё нормальным человеком, а не хипстерским хуесосом с бородкой на 300кк в наносек и модными наклеечками на крышке ноутбука. Этот язык симовол тех лет когда офисы IT компаний выглядили как обычные офисны, а не как модные кафешки для креативных дезигнеров.
Этот язык это рассвет IT индустрии. Именно он положил начало рассвету этой индустрии. В нём всё.
Анон, тебе непонять. Это не то что ты думаешь. Этот язык учат не васяны которым надоела пятёрочка и они хотят ВАЙТИ В ОЙТИ ШТОБЫ ДЕЛАТЬ САЙТЫ ПОД КЛЮЧ И ПОЛУЧАТЬ 300КК В НАНОСЕК. Здесь людям плевать на деньги, на то есть ли на этом языке работа, здесь сидят онли идейные.
Не надо шутить с байтоёбами, блядь. Здесь другие ребята. Это не питонисты, это не похапе макаки. Анон, твои модные фреймворки здесь просто обоссут. Это тред отборных байтоёбов блядь! Они всё разнесут! Они всю твою веб студию пройдут за один час! Они взорвут все твои макбуки, всех твоих верстальщиков, девочек-дизайнеров. Аноны, ты — макака. Ты остановись, блядь, ты кончай, ты джаву спрячь подальше на склад. И забудь про своего Джобса. У нас был один мудак, неосилил книжу Ритчи, блядь — и был выпизднут отсюда. И другой чудак был, плюсы не осилил на Страуструпа выёбывался — и также получил струю мочи в листо. И ты повторишь ту же ошибку. Ты похапе забудь, похапе твой отработал своё, блядь. Ты подумай о будущем веб индустрии: она гибнет! Твои джуниоры бегут из этой отрасли. Там никто не хочет работать, в вебе, никто! У тебя обезъянник, блядь! CSS, HTML, JS! Это… инструменты макак, блядь! Ни души, блядь, ни управления памятью нету у вас, нет разработчиков! Всё айти читает Ритчи, Страуструпа, блядь. Операционные системы, — только C\C++, блядь. И C++ здесь — C! Вот здесь любят байтоёбов, а тебя — презирают, блядь, презирают!...
Ты на чем прошивки будешь разрабатывать, додик? На крестах или расте, где бинарник весит больше твоей мамки? И к тому же медленнее (на таком уровне разница даже в несколько микросекунд играет роль)
Лучше, чем С, для самого низкоуровневого байтоебства еще не придумали и походу уже не придумают.
Из современных языков только C\C++ нужны, остальное нинужно.
Интересно а на нём только прошивки писать можно? А можно на нём написать графическую программу с GUI для вывода графика и построения функций?
Блять, ну сам-то подумай. Можно. А потом графиками рисовать картинку Дума, после чего из всего этого состряпать прошку и запустить на осциллографе.
Не, я имею в виду нормальные графики хорошего качества а не пиксельное гавно. Вообще можно ли на СИ такое сделать? Вот как на пике.
Вопрос удобства. Плюсы оказались удобнее сишки, сишка - удобнее ассемблера, ассемблер - удобнее двоичных кодов.
А по какой причине может быть такое, что этого нельзя сделать?
Да хоть на ассемблере. Все эти алгоритмы растеризации линий есть и не очень сложные - нужно лишь абстрактный массив заполнить цветами, и нужен какой-то интерфейс, который сможет это отобразить на экране - например, это может быть функция ос или просто указатель на область памяти с экранным буфером. Или осциллограф, но тогда ему уже совсем другой массив нужно заполнять другим способом, так как другие аппаратные требования.
Следовательно пользоваться надо тем что удобно, а не архаичным говном
Я просто ньюфаня и пока даже не представляю как подобное делать. Максимум что у меня было это питоновские графики, которые по сути были готовой библотекой, а мне интересно знать как сделать график на более низком уровне. Поэтому я вкатываюсь уже месяц в СИ.
Ну дерни SDL2 или WinAPI. Готовых средств из коробки нет, graphics.h никто не поддерживает уже хрен знает сколько.
>а потому что счётчик \n считает, а её считать нельзя. иначе программа будет некорректно пробелы считать.
Я про то, что ты дклаешь
if (c == '\n') putchar('\n');
вместо
if (c == '\n') putchar(с);
То что обрабатывать '\n' надо отдельно, это понятно.
а спасибо, щас пофикшу. понял, анон. спасибо огромное
Товарищи, посоветуйте инструмент для построения диаграмм зависимостей в исходном коде. Есть исходники опенсорсной БД на С. Какую утилиту можно натравить на эти исходники, чтобы получить графическое представление того - что откуда вызывается. Желательно еще, чтобы на основе make-ов можно было понять какие исходники в какие .so группируются
А как сделать так чтобы функция изменяла те переменные которые она получает?
Указатели. Передавать нужно будет &адреса переменных, а не сами переменные, как в scanf.
спасибо, огромное уже полез гуглить.
void myfunc(int ★a, int ★b, int ★c)
{
★a = 0;
★b = 0;
★c = 0;
}
int main()
{
int a, b, c;
myfunc(&a, &b, &c);
return 0;
}
спасибо, анчоусы. я уже в гугле прочитал про указатели, не нужно более.
В данном случае строго наоборот. У указателей другое назначение, но присунуты через жопу из за отсутствия ссылок.
а) как у переменной, б) перемещаться по памяти.
Для данной задачи ничего этого не нужно, нужен только алиас переменной, чтобы её менять. Указатель же привносит кучу ненужных мусорных действий и потенциальных проблем.
Сколько синтаксического сахара достаточно для одного и того же назначения?
Так я помимо связи бинарников между собой, хотел еще вызовы в коде - графически отобразить, и то - в какие .so какие искодники собираются, насколько это возможно
в гугловых гайдлайнах разрешается использовать только ссылки на константы. Если функция должна менять аргумент, требуют использовать указатель, чтобы продеонстрировать, что функция имеет сайд-эффекты.
...
это достаочная разумное соглашение, а сним у ссылки-аргумента функции остаётся только одно применение - оптимизация. Но во многих случаях имеет смысл просто передавать структуру по значению.
>в гугловых гайдлайнах
я тебя умоляю щас бы думать что люди из яндекса\гугла в чём-то разбираются. там такие уёбы работают, особенно в гугле. индусы, негры, азеятки всякое дерьмище собранное по квотам. с каких пор они стали арбитрами по СИ? пусть
понял. а когда нужно использовать while а когда for? они же по сути 2 идентичных цикла.
Гугл это тырпрайз, галера рабов, никто там ничего не выбирает, как сказано, так и делают. Хороший, дебильный аргумент - заткнуться и не думать.
Там 2 пизды карлицы и чтобы с ними обняться нужно самому присесть слегка на корточки вот все и по приседали.
Все крупные айти компании это галеры рабов с уёбищными вертикальными системами. Работать там можно только если ты макака. Поэтому индусы и азиаты просто как мухы на гавно липнут во всякие микрософты, гуглы, интелы.
Также очень удобно веб-макакам работать в таких компаниях где удобно срать только строго своим стеком и не разбираться ни в чём другом, мол всё остальное не мои проблемы. Всякие девачки верстальщицы и мамкины хипстеры на пыхах выигрывают от такого.
Но для творческого задрота на сях и плюсах это насилие над собой, душа просит свободы и творчества. А не убого высера кода ради бабла похуй что он может быть вообще не нужон и бесполезен, главное высрать.
Вообще работать айтишником и кодить дома ради интереса это разные вещи. Когда работешь айтишником там самое главное что выполнить задачу в поставленные сроки, она может быть неоптимизированна иметь какие-то баги, но главное чтобы тёта срака могла в нужный срок вводить свои бухалтэрские данные.
А дома ты пишешь, код и потом шлифуешь\переделываешь его доводя до идеала, вот это творчество.
Вернулся бы ты в свой МВП-тред.
А ещё меня бесят европейские(в американских не работал, но думаю что там также) компании. Их офисы, нахуя они офисы превращают в подобие детских садов или комнат отдыха. Какие-то петушиные офисы с классическим КРЕАТИВНЫМ ДИЗАЙНОМ всё в каких-то ярких развесёлых тонах, куча диванов натыкано, кухни эти маразм короче. Мне в такой обстановке работать неуютно, почему нельзя сделать классический серый строгий офис. Не офисы, а какие-то дома отдыха. Хотя в России в последнее время тоже мода пошла на эту креативность уебанскую.
Когда хочешь, без разницы, for - всего лишь сахар для while.
Если у тебя последовательный обход от n1 до n2, то лучше for - ведь он призван уменьшить количество строк и повысить лаконичность в таких случаях. Во всех остальных случаях с более сложными условиями выхода - while. Ещё есть подозрения, что for лучше оптимизуется компиляторами.
Ещё есть особый случай сахара for (;;) для бесконечного цикла, где для while придётся писать через довольно таки уродское while(1).
Причём особо удивляет когда погромисты с хабара да и вообще хвастают как дохуя платят в ойти, так дохуя что хватает снимать однуху 22 квадрата замкадом и ездить на квашкае в кредит на 7 лет, и 20% зарплаты тратить на парковку у работы.
И главное остальные верят в этот бред. Поехал в Риге смотреть квртиру в деревянном доме 27 квадратов за 16.5 к с начатым ремонтом. Маклерша оказалась знакомой родителей моей жены, хули этож деревня 600к. Вобщем после осмотра ценник врубила 16.8к, а наследующее утро уже блять 17.3к, видимо потомучто я айтешник. Я охуел с такой наглости, т.к. в объявлении двухнедельной давности указано 16.5к, а месяц назад было 17к. Сейчас буду несчадно вертеть эту тётку и тянуть с покупкой пока сама не скинет до первоначальной цены.
Это пиздец товарищи что вы творите рассказывая про "неебические" зарплаты...
Одно слово, айтишники - уебаны, которым пальцы сцука надо вырывать.
спасибо большое, анчоус, за подробные объяснения. благодарю ещё раз.
Да нет никаких зарплат в айти высоких. Я погромист с опытом. Самые максимальные зарплаты в России у вайтишника могут быть 200-250 тысяч в месяц максимум и это только в Москве. И таких вайтишников на 200-250к в Москве единицы. Единственный шанс заработать на айти огромные деньжища это высрать какой-нибудь ёба-продукт которым будет пользоваться быдло (ОС, игру, прилу уровня тиктока, сайт знакомств и т.д.). Но даже там не всё так просто, высрать много кто может, это нужно всё разрекламировать(отвалить огромную кучу бабла маркетолухам, пиарщикам, сммщикам), потом даже если ты будешь сам писать тебе всё равно пнадобятся всякие дезигнеры и прочие специалисты в айти по второстепенным технологиям в которых ты не ебёшь ничего или ебёшь, но недостаточно.
И то после всего этого не факт что твой говно софт взелтит и его кто-то будет покупать. Халявы в айти в этом нету. Единственная причиная по которой его раскручивают что там на работу можно без дипдлома устраиваться и для обучения хватит компьютера с интернетом дома, вот всё быдло с пятёрочек и валит в айти. Да и то они сейчас тот же веб обвалили уже эти вкатывальщики, т.к. в веб проще всегов катываться всё быдло бежит туда чтобы побыстрее 300кк в итоге, там джуниоры нахуй не нужны и сеньёорами уже пятки жечь начинает. Яркий пример хохол с ютуба который приехал в сша с опытом работы на похапэ и отсасывает там без работы уже несколько месяцев. Даже с опытом веб макаки уже не везде пристраиваются.
Чтобы в айти быть нужно это хуйню любить, не то чтобы я его прям так люблю просто у меня другое больше ничего не получается особо. Сам в веб пытался, мне вообще все говорили "да ты там вообще все раком нагнёшь ты же на сях-хуя опыт имеешь" а меня стошнило от него только на стадии изучения CSS, не моё это всё. Роднее на заводе пилить всякое гавно для станков.
>все еще обоср
да, там "" в аргументы добавить надо, конечно же
я даже компилить не пробовал лул
>это нужно всё разрекламировать(отвалить огромную кучу бабла маркетолухам, пиарщикам, сммщикам)
Нужно пилить инновационный продукт, типо ютюба в свое время, чтобы не конкурировать с существующими гигантами. Ну это мои маняфантазии.
Ну иновационный продукт это то что я не стал упоминать так как скорее всего никому из присуствующих в треде это никогда не светит. Иновационный это не то что продукт который будет быдло покупать, а продукт который действительно будет первым в своём роде, прорыв. Ну это нужно быть и погромистом дохера и знать чего рынок хочет. Это вообще самый анриальный вариант. Людей которые ты вылезли едининцы.
Другое скажу, что скорее всего 1995-2005 были пиком инноваций в сфере компьютерных технологий. Мы шли к этому с начала 60-х и 70-х, и все монополии и главные игроки рынка появились в конце 90-х, и что интересно, некоторые из них первый десяток лет были полуживые, типо Netflix'a того же, но появились же они тогда.
Своего рода это же было с самолестроением и автомобилестроением, и с другими областями инженерии. Да, есть маленькое исключение в виде Маска, и то с натяжкой его можно поставить в один ряд с Генри Фордом в индустрии автомобилестроения и с его Теслой, которая хорошо забытое старое. Так индустрия после середины 50-х развивалсь итеративно, эволюционно, медленно, с тонким изучением маркета и методом брут-форса по отношению к потребителю когда у потребителя есть смартфон, купленный в 2012 году, тут ещё сломать голову нужно, какая фича заставит его купить новый, а не с помощью гениев-изобретателей и революций в построении автомобилей которые бы переворачивали всё верх дном.
И это не значит, что в мире все изобретено, и гениев больше не будет, но в мире компьютеров возможно новых гуглов не будет.
Ну это я так, высрал.
Тебя не смущает, что у азиатов самый высокий показатель IQ в мире, также самое лучшее в мире образование? Индусы саморазвивались тысячелетия и теперь вникают в суть чего либо очень быстро, осознанность делает свое дело. Ну а негры - негры просто любят работать, они упрямые что пиздец и тащат таски тупо на выносливости. Такой стак всяко лучше, чем стак из ленивого ваньки, жадного еврея и гейропейца.
IQ это тест для обезъянок на него можно настаскать даже тупого хача если он будет постоянно эти задачи решать. Загуглил хоть бы для кого этот тест изначально изобретали, IQ блядь.
А тебя не смущает что такая "великая" азеятская нация которая изобрела якобы и бумагу и компас и порох с таким IQ последние 1000 лет были в жопе откровенной, на примере того же китая. А сейчас якобы в расцвет их все их товары технологически отстают от европейских и американских. Даже у японцев. Азиаты могут как обезъянки повторять и осваивать технологии. Они не творческая нация, они очень трудоспособны и могут как роботы по одному и тому же алгоритму задротить сутками, чего нет у белых. В этом сила азиатов.
лол, гугли AI Winter.
в смысле, с простой ссылкой, чтобы функция имела сайд-эффекты
в книги ричи, например где он ещё в первой главе пишет про extern тупо сделать глобальную перменную и всё. никакой лишней путаницы. а макаки из гугла внутри своей уютной индусско-китайско-лесбиянско компании могут какие угодно стандарты лепить
Каеш, глобальную переменную. функции вообще не нужны, всё нужно в мейне писать, если где угол нужно срезать - ебашь goto.
Ну так речь шла изначально о том чтобы функция получала переменную и её изменяла походу работы. Гораздо проще сделать глобальную и всё. А как это влияет на идеологию функции я не знаю, ибо функции нужны для того чтобы кол-во кода сократить просто, функция это какой-то кусок кода который можно вызывать в различных частях программы без копирования всего кода.
Смотри, это правда, Джон Кармак может написать кваку ни сишечке, используя глобальные переменные.
Но ты наверняка не Джон Кармак, а васян (как и я впрочем), потому лучше обойтись функцией с аргументами-указателями, и не плодить зазря глобальных переменных.
Везде, где нет хачкело-дебилов, у которых программирование это "сайд-эффекты". Хорошо бы и в си-треде не было, но дерьмо уже растеклось.
1) a = 1, b = 2, c = 3;
a = b = c; - undefined behavior? Операция присваивания происходит справа налево, однако неизвестно в какой момент результат операции должен был записан в переменную, ведь sequence points в выражении нет. То есть мы можем получить такой результат:
a = 2, b = 3, c = 3
2) int i = i++; - не undefined behavior в отличие от:
int i;
i = i++;
? Судя по стандарту, int i = i++; это не undefined behavior точка следования в объявлении с инициализацией на момент завершения вычисления инициализирующего значения. Пример. Рассмотрим выражение «int a = ( 1 + i++ );». Точка следования вставляется после вычисления выражения «( 1 + i++ )»;
Однако какова в таком случае должна быть логика работы данного кода? На машине, где все байты установлены в 0, я понимаю работу строчки int i = i++; следующим образом:
Компилятор видит expression i++. Постфиксный инкремент. Следовательно, откладывает инкремент i после выполнения присваивания. Ставим SP после оценки нашего expression, где i в rvalue == 0. Затем i = i, то есть присваиваем 0 переменной i. После видим ; - ставим еще один SP. После чего компилятор должен сделать инкремент i; То есть в итоге i должен быть равен 1. Однако, когда я printf'аю результат, то в консоль выводит, что i имеет значение 0. Следовательно, я неправильно понимаю работу этой строки, верно? Ведь, опираясь на стандарт, должно быть определенное поведение, не должно быть никаких отсечений модификаций переменной и т.д. В чем тогда суть SP в данном случае? Как компилятор разбирает данную строку? Поясните пошагово, пожалуйста
3) 'звездочка'ptr++ = x++; - неопределенное поведение? Или неопределенное поведение только в случае модификации одной и той же переменной более одного раза между двумя SP?
Столько часов разбираюсь с этой темой, но некоторые моменты все никак не могу прояснить. Очень надеюсь на развернутый и подробный ответ по каждому пункту. Тема важная, другим анонам тоже будет полезно знать
1) a = 1, b = 2, c = 3;
a = b = c; - undefined behavior? Операция присваивания происходит справа налево, однако неизвестно в какой момент результат операции должен был записан в переменную, ведь sequence points в выражении нет. То есть мы можем получить такой результат:
a = 2, b = 3, c = 3
2) int i = i++; - не undefined behavior в отличие от:
int i;
i = i++;
? Судя по стандарту, int i = i++; это не undefined behavior точка следования в объявлении с инициализацией на момент завершения вычисления инициализирующего значения. Пример. Рассмотрим выражение «int a = ( 1 + i++ );». Точка следования вставляется после вычисления выражения «( 1 + i++ )»;
Однако какова в таком случае должна быть логика работы данного кода? На машине, где все байты установлены в 0, я понимаю работу строчки int i = i++; следующим образом:
Компилятор видит expression i++. Постфиксный инкремент. Следовательно, откладывает инкремент i после выполнения присваивания. Ставим SP после оценки нашего expression, где i в rvalue == 0. Затем i = i, то есть присваиваем 0 переменной i. После видим ; - ставим еще один SP. После чего компилятор должен сделать инкремент i; То есть в итоге i должен быть равен 1. Однако, когда я printf'аю результат, то в консоль выводит, что i имеет значение 0. Следовательно, я неправильно понимаю работу этой строки, верно? Ведь, опираясь на стандарт, должно быть определенное поведение, не должно быть никаких отсечений модификаций переменной и т.д. В чем тогда суть SP в данном случае? Как компилятор разбирает данную строку? Поясните пошагово, пожалуйста
3) 'звездочка'ptr++ = x++; - неопределенное поведение? Или неопределенное поведение только в случае модификации одной и той же переменной более одного раза между двумя SP?
Столько часов разбираюсь с этой темой, но некоторые моменты все никак не могу прояснить. Очень надеюсь на развернутый и подробный ответ по каждому пункту. Тема важная, другим анонам тоже будет полезно знать
>допустимо ли так писать?
Да, допустимо. И так лучше, чем вариант с войдом.
>>603921
while работает медленнее
>>603926
while более читабельный вариант в сложных нагромождениях, однако for - более быстрый. Если пишешь функцию для либы, то для оптимизации лучше использовать for Можешь почекать исходники некоторых функций из стандартных либ. Например, strlen. Или еще что-нибудь. Там встретишь for (; <exp> ; <exp>). Алсо for позволяет инициализировать несколько переменных в заголовке цикла. Например, for (int i, j, k, l, m; <exp>; <exp>), память под которые будет очищена при выходе из этого самого цикла. В случае с while тебе бы пришлось объявлять их до цикла, следовательно, они бы висели в памяти всегда.
>int i;
>i = i++;
>Судя по стандарту, int i = i++; это не undefined behavior
У тебя переменная неинициализированна, о чём ты, вообще?
>В случае с while тебе бы пришлось объявлять их до цикла, следовательно, они бы висели в памяти всегда.
Можно их в отдельный {} загон вместе с while.
Сначала говорят "си это ассемблер", а потом сидят переменные экранируют. Вас, пидарасов, нужно заставлять кодить на классическом бейсике со всеми глобальными переменными и переходами только по goto/gosub и никаких функций-хуюкций, минимум год, чтобы железно и навсегда поняли как программы работают. И только потом пускать на языки с абстракциями и пидарскими феласофиями. А то сразу лезут в говно не по уму, а потом кукарекают сивый бред.
>a = b = c;
>однако неизвестно в какой момент результат операции должен был записан в переменную
Ты не правильно понимаешь присваивание, мне кажется.
(b = c) присваивает переменной b и "возвращает" значение c. То есть даже если фактически на момент разбора a=.. значение b всё ещё не изменилось, сюда подставляется не значение b, а значение c. Нет гарантии, что в b будет нужно значение на момент записи a, но есть гарантия, что в a будет записываться нужное значение.
Компиляторы вон просто записываю одно значение по двум адресам, как будто бы там всегда есть скобки, если бы присваивание по каким-то причинам требовало явного возврата левого операнда, то с volatile оно было бы вынуждено записать и тут же прочесть значение b.
>int i = i++;
Как ты себе такое представляешь? Он либо пожалуется на то что такая переменная уже есть, либо левая i будет новой переменной в новой области видимости, и это уже код int a=i++. Если ты имел ввиду именно int i=i++, то этот код настолько же бессмысленный, как и int i=i; или int i=2*i;
Или ты хочешь писать код на подобии кода со второго пика? Тогда у меня больше нет никаких комментариев.
>>604872
Предположу, что он имел ввиду, что код с for занимает внутри функции всего 3 ячейки памяти (под i и с используется одна и та же), а если написать переменную вне for или {}, то i будет попадать во "глобальную" область видимости функции и нужно будет занимать четвёртую ячейку для c. Размер стека экономят, почему бы и нет?
хорошо, когда по функции понятно, что она делает.
по с++ функции с аргументом-ссылкой непонятно, по сишной функции с аргументом-указателем ясно, что она может поменять указатель сразу. но васяну приятно, что можно лишней букавы не писать, потому он будет высирать телеги про гугл, который не умеет в написание кода.
Твое пиздоболие имеет смысл только для тырпрайзо-помоек, где толпы тупых взаимозаменяемых макак жуют чужой код. Тут да, надо чтобы посторонним даунам было понятно как можно быстрее. Но за это расплачиваются лишними простынями блоатного говнокода. Но это норм, ведь тупые макаки и не против строчить однообразное говно, а что оно по сути бесполезный блоат, им похуй, деньги же платят. Им пообще похуй на то, что они пишут, хоть "хуй" на столе у соседа.
А тред как бы не про тупое говно, а про программирование, для людей , которым оно небезразлично. Ты знаешь, что сам пишешь, есть комменты, да даже в IDE по нажатию кнопки выскакивает прототип со всей инфой, включая комментарий. Проблем нет, и код чистый, понятный и надежный.
Да и вообще всё лирика. Просто здравый смысл: Если нужно менять переменную, используется она сама - ссылка, это прямое выполнение задачи. А указатель это а) другая переменная, которая не нужна, плодить лишние сущности. б) указатель работает не с переменной, как ссылка, а с памятью - низкоуровневой подложкой под абстракцией переменной. Это ничто иное как васянское костылестроение на пустом месте. Нет, понятно, если ссылок нет, приходится выкручиваться, но в плюсах же есть, а они та же сишка, так что оправдания говноедству нет.
спасибо за подробный разбор для ньюфани, анчоус.
>int i = i++;
>Как ты себе такое представляешь?
Обыкновенно. Переменная объявлена до прибавления, так что всё работает нормально, единичка прибавляется к текущему содержимому.
>пик 2
Это работает потому что функции одинаковые и вызываются друг за другом?
И в гегле прочитал, что объявлять функцию volatile бесполезно, слово игнорируется.
Нахуя ты в этом говнокоде разбираешься? Есть такая вещь как best practice, тупо следуя ей, ты избегаешь этих дебильных ошибок и говнокода.
>Переменная объявлена до прибавления
Так не бывает, оно не скомпилируется.
А если там новая область видимости (например {}) - то у тебя уже две переменных, а не одна. Вторая картинка - у них разные значения и разные адреса в памяти. Нельзя два раза написать int i=.. так чтобы это была одна и та же переменная.
>Это работает потому что функции одинаковые и вызываются друг за другом?
Считай, что это не работает вовсе. Это сработает только на одном компиляторе и на одних настройках. Да, так получается, что переменные в функциях попадают на одну и ту же ячейку стека. Но это супер плохой код, никогда не используй ничего подобного, и слово volatile тоже обходи стороной.
>объявлять функцию volatile бесполезно
Не бывает volatile функций, volatile такой же модификатор как и const, типы const int, volatile int и int - разные и функция к ним отношения не имеет.
А мы тут вашего залетного КУЗЬМИЧА в кружок отпетушили, принимайте пополнениезабирайте назад.
>>1605269 →
>>1605259 →
>>1605243 →
>единичка прибавляется к текущему содержимому
Просто не понимаю чего ты хочешь добиться. Тебе нужно единицу к какой-то переменной добавить, и чего бы ты не хочет добиться, есть способы намного более понятные другим людям и компилятору, без неоднозначностей.
То что там будет sequence points - код никак не замедляет, никакой дополнительной инструкции для этого не предусмотрено и это лишь абстракция. В действительности половины переменных вовсе не существует, и данные сразу между регистров пересылаются - если убрать все volatile из кодов со скриншотов, то там даже вызова функций не будет, там сразу будет в printf передано 20 и (скорее всего) 1 без вызовов te1/te2.
А если для чего-то хочешь понять как это интерпретирует компилятор - то смотри какой код он генерируется, но не будет никакой гарантии что код не поменяется на следующей версии компилятора, другой платформе или ещё где. Наверное, где-то в документации компилятора даже написано каким путём какая неоднозначность разрешается.
Кстати, вот ещё погляди, тебе понравится вывод программы скорее всего - если тебе интересны такие штуки про существование несуществующих переменных.
https://ideone.com/zSjw5N
>Так не бывает, оно не скомпилируется.
Ты тролль или дебил? Откуда взялясь еще строчка?
>типы const int, volatile int и int - разные
Но не лля возвращаемого функцией значения. Оно и так константа, ты не поменяешь, и c volatile то же самое, ничего не меняет и игнорируется.
Наверное, второе.
>Переменная объявлена до прибавления
Каким образом ты объявляешь переменную до подобного прибавления, в таком случае? Что ты имел ввиду под этой фразой?
>Откуда взялясь еще строчка?
>Если ты имел ввиду именно int i=i++, то этот код настолько же бессмысленный, как и int i=i; или int i=2*i;
У тебя два объявления в двух строчках:
int i ...
int i ...
Конечно ругается на переобъявление, но речь шла только об одной строчке:
int i=++i;
тут всё работает как и должно.
>речь шла только об одной строчке
И какой смысл должен быть у такой строчки? Начальное значение i не определено, какой результат ты рассчитываешь получить?
>>605386
Ага, ты прав, не смог добиться разного поведения функций с volatile и без. Но всё ещё не исключаю, что можно добиться разного поведения компилятора при разных типах из-за какой-нибудь оптимизации - плюсовый typeid выдаёт разные типы.
>какой результат ты рассчитываешь получить?
Прямой результат, блин, хватит тупить. Что написал, то и получил - увеличение переменной на единичку. Что неясно, алё?
А что не присвоил сначала значение напрямую, какая разница? Ты можешь сказать НИНУЖНО, но так ли в этом уверен? Если уверен, мои соболезнования.
Не понимаю, ничего не ясно. И, наверное, уже не пойму.
Ага, уверен абсолютно. Компилятор может подобным переменным присваивать начальное значение 117 и будет совершенно прав - ведь это соответствует стандарту. Но вряд ли это то, что тебе нужно. Программа и переменные - лишь абстракция и я спрашивал из какого начального состояния абстракции какое конечное ты хочешь получить после выполнения своей строчки.
Тут нет абстракций. Переменная использует память, а память всегда содержит данные, она так устроена железно. Не бывает пустой памяти, с черной дырой вместо данных, к которой нельзя прибавить число по причине отсутствия в ней числа как такового.
> while работает медленнее
Нет. for - полный аналог while, только с сахарком. for (expr1; expr2; expr3) { ... } разворачивается до { expr1; while (expr2) { ...; expr3; }} Но на самом деле большинство компиляторов даже while (x) {...} разворачивает дальше, в if (x) { do { ... } while(--x) }.
> память под которые будет очищена при выходе
Не будет. Оставить автоматические переменные висеть в стеке до выхода из функции дешевле, чем заниматься лишней очисткой.
Чего ты с ним споришь, он же просто троллит тупостью.
https://pastebin.com/Ed83qm4v
как избежать ебучих кодоповторений в свич-кейсах?
>память всегда содержит данные, она так устроена железно. Не бывает пустой памяти, с черной дырой вместо данных
Ну конечно же бывает. Буквально вчера была на хабре статья про ретрожелезо. Там при чтении несуществующего адреса памяти в регистр приедет мусор, который находится в тот момент на шине данных с прошлых инструкций.
> как избежать ебучих кодоповторений в свич-кейсах?
Ты можешь в отдельной функции в case-ах заготавливать параметры (read_length, signedness, endianess, format_string - вот это все), а читать, инкрементировать указатель и форматировать после switch, централизованно. А второй функцией парсить остальные спецификаторы типа A или S, выставляя флаги. Или даже собрать это все в табличку и выкинуть свитчи нахуй. У меня от тебя kaitai struct. Еще имена и кодогенератор зделоть, и будет заебись, никакой сраной джавыскалы.
Можешь пример показать?
>при чтении несуществующего адреса
Переменные создаются в существующей.
Сначала добавлял несуществующие строчки как оргумент в пользу своей тупости, теперь добавил несуществующую память (настоящий баран, прёт одним способом). И это несмотря на то, что носом ткнули еще в первый раз (и необучаемый)
>память всегда содержит данные, она так устроена железно.
Открой для себя защищенный режим и виртуальную память
А виртуальная память где находится? В десятом измерении далекой галактики? Или может всё таки в физической памяти?
Си - не про физическую память. Язык описан в терминах абстрактной машины, поэтому компилятор, который при попытке int k; printf("%d\n", k); будет делать exit(1) - это абсолютно нормальное, документированное поведение программы. Более того, именно это (в числе прочего) и происходит при сборке с -fsanitize=memory.
>не про физическую память?
Такого никто не говорил, опять придумываешь из жопы бред, разговаривая сам с собой.
Какая бы ни была память, всё равно основана на физической, где данные есть всегда. Я честно не понимаю, зачем настолько невежественные люди лезут в си, где это важно. Иди в языки высшего уровня, там похуй, сиди в своих маня-абстракциях и нормально будет.
Виртуальная память может нигде не находиться. Можно сделать так, что у тебя страница памяти будет при чтении выдавать нули, а при записи данные будут уходить вникуда, и никакой физической памяти у нее не будет.
Железо ничего не знает про виртуальную память, это абстракция операционной системы. Кури мат. часть.
>Язык описан в терминах абстрактной машины, поэтому компилятор, который при попытке int k; printf("%d\n", k); будет делать exit(1) - это абсолютно нормальное, документированное поведение программы.
Противоречит стандарту.
Хотя можно и сейчас настроить компилятор что он будет выдавать ошибку на таком коде.
>при чтении выдавать нули
Вот именно, может выдавать нули или не нули, но не может не выдавать числа. Числа всегда есть, потому что так устроена память, хоть сколько раз манявиртуальная.
>Железо ничего не знает про виртуальную память, это абстракция операционной системы. Кури мат. часть.
Виртуальная память реализуется процессором. Опять же, гугли "protected mode"
Может выдавать что угодно, хоть тред с двача. Хотя для этого надо будет ядро линукса патчить.
Я в курсе, спасибо.
Шутки шутками, но подведу простыми словами.
>int i=i++;
Нормальная запись, имеющая нормальный смысл, по одной простой причине: НЕ БЫВАЕТ НЕИНИЦИАЛИЗИРОВАННОЙ ПАМЯТИ
Память по дизайну всегда инициализированна данными, не может не быть, её невозможно очистить, только заменить одни данные на другие, поэтому с памятью можно работать в любой момент.
В коде выше, переменная объявлена до работы с ней, поэтому функционирует как и должна. Никаких проблем и странностей нет.
Чет ты какой-то шизик
> Противоречит стандарту.
If the lvalue designates an object of automatic storage duration that could have been declared with the register storage class (never had its address taken), and that object is uninitialized (not declared with an initializer and no assignment to it has been performed prior to use), the behavior is undefined.
Совершенно не противоречит.
В джаваскрипте -да, в Си - нет. Си это машинный язык низкого уровня, тут переменная это простое число, адрес памяти с данными, прямая проекция памяти, общей сырой памяти, а вовсе не какой-то абстрактный объект сам по себе как в языках высокого уровня. Посмотри на 3-ю картинку >>604918 , цветом подсвечен соответствующий ассемблерный код. Каждая всего всего лишь номер, адрес в памяти: 4, 8, 12. Ты спокойно можешь попасть из одной переменной в другую, никакой инициализации не требуется, абстракция языка абсолютно минимальна, ты сидишь голой жопой на сырой памяти.
Жавамакака не палицаxddd
Даже у сишки под капотом куча абстракций, а в malloc.c сидит оптимизируюший менеджер памяти куда 90% сишников не заглядывает.
Думаю, стоит ли расказать ему что ОС чистит страницы памяти перед тем как отдать их процессу?
> Ты спокойно можешь попасть из одной переменной в другую
Не можешь. Нарушаешь правила strict aliasing или ходишь за пределы переменной - дружно идешь нахуй, помахивая undefined behavior. Например, компилятор может притвориться, что "не заметил" доступ в другую переменную, и ему похуй, что у тебя там в голове за "машинный язык низкого уровня". Вот, например, так: https://godbolt.org/z/c2vbPJ
Нет, потому что "переменная" это лишь число - адрес, а значит она не существует, пока к ней нет обращения. Обращение может быть хоть на запись, хоть на чтение, только тогда появляется соответствующая инструкция с правильным числом-адресом. Совсем не нужно сначала писать, а потом читать, ведь память уже есть. Если у тебя программа только из объявлений:
{
int a,b,c,d,e,f;
}
то тут кода вообще никакого нет, ибо с памятью ничего не происходит, нет не только инициализаций, но и ничего не создается, потому что нет объектов, создавать нечего, ведь память и так есть уже, а больше ничего не нужно.
>Не можешь. Нарушаешь правила strict
>Не можешь перебегать дорогу в неположенном месте. Нарушаешь правила дорожного движения
Можешь. Пошел нахуй, дебил.
Я специально стараюсь как можно меньше слов и идей тебя заставлять обдумывать, но всё равно получается:
>- Там переменная инициализированна.
>- Нет
>- Нет?
>- Ряяя ты не умеешь читать!
Приводить в качестве примера оптимизации в столь оторванном от реальности контексте - бред.
В подобной короткой хуйне даже твою мать можно заоптимизировать до пары сотен кг.
Ты подрочи эти переменные в 10 разных местах, сделай асинхронное обращение к ним какое, а потом покажи, как это оптимизед эвэй будет.
>Приводить в качестве примера оптимизации в столь оторванном от реальности контексте - бред
Странный ты...
Ты не понимаешь, вот int i=i++; это нормальный реальный контекст, постоянно так в продакшене делаю, лично цукерберг одобряет.
Во первых это другой анон. Во вторых доп память могла находиться в картридже. Который внезапно могут вынуть во время работы программы.
$1000 и внесу.
это шутка штоль?
Вот смотри, ++x и x++ означают пре- и постинкремент. В связи с этим я требую, чтоб ==x и x== означало пре- и постэквивалент. Чтобы в первом случае x приравнивался к x до вычисления объемлющего выражения, а во втором случае - после.
char buf = "0000";
от такого:
char buf = malloc (5);
//заполняем буфер теми же четырьмя нулями;
//и ставим \0 в конце;
Напиши buf[2]=123 в первом случае и во втором.
В первом случае эта область вроде как только для чтения и в неё нельзя записывать.
Аноны ниже правы, но и нет.
У тебя в первом случае выделяется память на стеке(статический), во втором - в динамической памяти(динамический, само собой).
Нет, это не стек.
Там идёт какая-то область памяти до (или после) глобальных и статических переменных, и строковые литералы где-то там. Но это не стек. Стек, это char buf[5]="0000".
Интересно.
Ведь 8 и 11 кажутся одним и тем же с точки зрения выделения памяти, ан нет.
А char x[] = "test" будет равносилен 7 и 8 строкам?
> кажутся одним и тем же с точки зрения выделения памяти
Они и есть одно и то же. Просто шизик -O3 забыл. И использовать переменные забыл.
Нет, он скорее забыл компилятор указать.
Даже с -O0 всё нормально: https://godbolt.org/z/UGfv2U
>Специально для студентиков.
От школьника? Чтобы переменная была статической, надо ее либо объявлять глобальной вне всех функций, либо внутри функций с ключевым словом static.
-O3 тут не причем. И использование переменных тоже.
>>606974
> Аряяяя не тот компилятор
Классика. Ну посмотри что генерит clang, если msvc по каким то надуманным причинами тебя не устраивает.
>>607047
А ты не очень умненький, как я посмотрю. Переменная создается на стеке, но вот значение хранится в статической памяти.
Ну и? Ассемблер не знаешь что ли? Все верно. Открой отладчик и посмотри, если не веришь. Статические данные в .rdata разделе.
Вы заебали это кормить. Нет, MS тоже умеет обоими способами массивы инициализировать: https://godbolt.org/z/B1515J просто у них другие взгляды на эффективность
Ты дурачок? Я тебе скринов наделал из отладчика, компилил шлангом x64. Глаза то открой. Жду твои вскукареки по поводу не той ОС.
Это мой скрин и есть. Я понимаю, что ты нихуя не понимаешь этот код. Я тебе объясню, это СТЕКОВАЯ СТРОКА. Шланг же пихает строки в .rdata. Тупой же ты дегенерат.
Вот это проекции.
Ладно, давай на пальцах, как с отладчиком.
1. Тебе чем то не угодил msvc и ты впример мне кинул говновывод gcc >>606974
2. Я указал тебе посмотреть на вывод нормальных компиляторов msvc gcc >>607150 Твои гринпук текст ИМПЛАИНГ сборка GCC == CLANG и CLANG != MSVC. Хотя заметь, я нигде не писал, что clang сгенерит такой же код как и msvc, я сказал, что оба компилятора генерят правильную сборку в отличии от gcc. (Вот здесь твой обсер, маня, ты сам чего то там напридумывал не разбираясь в теме и смеешь что-то пиздеть).
3. Итого: gcc - оптимайзит в стек ( кладет хуй на программиста ), msvc - кидает все статик, кроме явного выделения на стеке (все правильно), clang кидает все в статик (чтобы наверняка)
4. ТЫ - выдаешь вывод clang'a и gcc за одинаково равных, хотя они в корне разные и конфликтуют друг с другом >>607281 при этом называя msvc говном.
Выходит ты обосрался то. Типичный хейтерок + низкоквалифицированная маня.
>Классика
Просто не смог пройти мимо студии и не тыкнуть в неё пальцем.
>посмотри что генерит clang
Ну давай, смотрю. Вторая и третья строчка на соседних адресах, в стеке. Точно не уверен, но и в msvc будет то же самое (оно не запускается на годболте).
Всё что я имел ввиду - на пике. Я имел ввиду, первая строчка хранится в readonly-памяти, вторая и третья хранится в стеке, а четвёртая(даже не строчка) в куче. А пятая, которую я добавил в области глобальных и статических переменных.
То что gcc кладёт сразу значение, а clang или msvc зачем-то копирует из какой-то залупы никак не меняет то место, где по факту оказывают расположены байты строчки.
Не понимаю в чём ты меня убедить пытаешься, и не понимаю что ты имел ввиду, когда написал что вторая строчка - статическая память, ведь адрес её байтов такой же, как и адрес байтов стековой строчки.
Найс, ты мне линкуешь мой пост называя его твоим. Это уже верх фарса даже на дваче.
Лол, просто прекрати, ты каждым постом умудряешься загнать себя еще глубже в яму, которую сам себе вырыл.
Ни в чем, это вы доебались со своими компиляторами, пидорасы блять.
https://godbolt.org/z/ZU93TP
Расписал для дебилов, надеюсь теперь всем все понятно.
>{'t','e','s','t'};
А кампот?! '\0' не забывай, он может, но не обязан быть в пятой ячейке твоего [5] массива
Почему кланг хранит стековый массив в данных? Типа "памяти хватит всем, давайте хранить массивы в двух экземплярах"? Хотя, я скорее поверю, что у говнокодеров так просто получилось и решили не заморачиваться исправлением, работает же, ну и хрен с ним.
Потому что блядь как он тебе запилит при загрузке экзешника еще не существующий стекфрейм функции в которую еще не зашли?
Хватит ли его для работы на c/c++? (Смогу ли я на нем написать и протестировать свою ось?) Если да, то какой линупс ставить? Если нет, то чего не хватает?
Не подумал, бывает. Но всё же, как понимаю, разница где хранятся данные. Прямые стековые в коде и сразу пишутся, а из данных грузить надо, это по идее медленно.
Смысл стековых данных что их не "еще не существует" при входе в блок и "уже не существует" при выходе. Они существуют только пока процессор внутри блока. И всё это за счет принципа FIFO, где все переменные после выхода из функции грохаются кхуям и потом это место затирается уже совершенно другими переменными из другого блока/функции.
Ну как не существуют. Все константы из исходного хода хранятся в экзешнике и загружаются в память при его старте. Только стековые находятся в коде, прямо в инструкциях которые заносят их в стек, а другие в сегменте данных и загружаются оттуда. Смысл стека же в скорости, а грузить из жопы не очень быстро. По крайней мере я так понимаю, от чего возникает вопрос говнокода кланга, который всё в данные пихает, а мог бы и в стек, раз программист так пишет.
Кто-нибудь линтерами пользуется? Или только на компиляторы полагаетесь, а в стиле на свои руки?
Очень толсто.
1 2
3 4 5 6
7 8 9
10
(Т.е. в каждой строчке неизвестное кол-во чисел)
Надо записать в матрицу:
1 2 0 0
3 4 5 6
7 8 9 0
10 0 0 0
Размер матрицы заранее известен
Да двачеров пока дождешься...
Уже свой велосипед придумал:
for(i=0; i<n; i++)
for(;;){
scanf("%d%c", &x, &c);
...
if(c=='\n')break;
}
> а из данных грузить надо, это по идее медленно
Нет, не медленно. Строковые инструкции в современных процессорах опять починили, и rep movs будет быстрее сколько-нибудь длинной серии mov. Общая логика у компиляторов такая: много инициализаторов - данные копируются из "шаблона" одним циклом, "шаблон" в секции данных (если линкер .text и .rdata не смержит), мало инициализаторов или между ними дырки - переменная инициализируется инструкциями по кусочкам, разными способами (например, иногда массив предварительно обнуляется, иногда нет, иногда SIMD, иногда по байтам - зависит от конкретной ситуации и конкретного компилятора; кто-то, вроде бы 16-битный ватком, умел push-ами массивы собирать). Собственно, я пример уже приводил для студии: https://godbolt.org/z/B1515J у других аналогично.
>Смысл стека же в скорости, а грузить из жопы не очень быстро.
Аты не очень умненький. Процессору хоть стек хоть хуек. Скорость зависит от того, нужно ли подгружать что-то в кэш (если очень по-простому). Вообще, я просто охуеваю, собрались васяны и давай там обсирать: тут у них кланг неэффективно делает, тут гэцэцэ.
а) не стоит путать формальную семантику Си с её реализацие конкретным компилятором конкретными свичами. компилятор должен выдать программу. которая соответсвует семантике абстрактной магины си. ВСЁ, никаких блядь "переменных на стеке", никаких прямых обращений к памяти НЕТУ.
б) у васяна могут быть странные представления о том, как проц выполняет машинные коды. Тип, он берёт инструкцию из памяти, и выполняет её, ещё одну, и выполняет. На самом дела процессор берёт сразу дохуя инструкций, и блядь делает какую-то адскую ёбань типа, заполняет пайплайн, предсказывая джампы, пытается избежать кэшмисса. Очень много чёрной магии, гарантируется лишь то, что конечный рещультат однопоточной проги будет такой, какой он будет по представлениям васяна. Чтобы понять, что быстрее, а что медленне, нужно реально курить маны.
в) компилятор пишут достаточно умные люди, умнее среднего васяна, эти люди хотят выжать максимум производительности проца и эти люди курили маны. Перед компилятором стоит дилемма: пожертвовать производительностью, или наказать васяна хуём за то, что он не читал стандарт. Решение этой дилеммы часто зависит от флага оптимизации.
> Скорость зависит от того, нужно ли подгружать что-то в кэш
Ты сам себе противоречишь. Стек постоянно пидорасится, поэтому стекфрейм гарантированно в кэше. Тут он прав.
Если бы такие книги ещё были.
Максимум, наверное, есть в каких-нибудь проектах инструкция для начинающего контрибьютора.
Поэтому придётся просто сидеть, целыми днями вникать в исходники, гадая о назначении функций по их названиям, редким и кратким комментариям, и играясь с ними в отладчике.
Напиши свой драйвер символьного устройства. Задача простая, на C, ещё и архитектуру ядра чуть изучишь.
Не идиотская идея же.
хотя можно задавать максимум дефайном, инициализировать умолчания, {} не превышает дефайн, потом смотреть, равны ли значения инициализированным, если да, то за пределами, хотя это мозгоёбство.
чёрт, сайзофом тоже можно вроде.
Но тут же C++, не?...
https://ideone.com/fork/y9ingp
>Какая ему еще нужна скобка перед точкой с запятой?
У тебя 36 открывающих и 30 закрывающих скобок...
Спасибо, брат. Из-за такой хуйни столько тупил...
Если ты хочешь ради денег - сразу нахуй.
А если интересно, то в любой даже самой непопулярной сфере можно найти профессию.
> Если ты хочешь ради денег - сразу нахуй.
Неужели все настолько плохо?
> А если интересно, то в любой даже самой непопулярной сфере можно найти профессию.
А если я хочу несложные программы для себя писать - с какого языка стоит начать, если до этого почти не программировал?
>Неужели все настолько плохо?
Что значит плохо? Хуевое решение при цели стать миллионером пиздовать в промышленные альпинисты.
Можно пойти в экономику, там шансов будет в сотни раз больше, хотя хороший пром альпинист вполне может через лет десять иметь свой первый лям.
А может и два квадрата.
Несложные. Ну я вот на си для себя делал программу, которая во внешнем файле искала нужное слово и выводила предложение целиком.
Например в файле
123 какой-то текст 1
222 какой то текст 2
345 какой то текст 3
...
Вбиваешь номер и консолька мне выдавала текст на нужной строке.
Ещё хочу бота для твича своего сделать.
Ну и по максимуму я хочу сделать какой нибудь платформер уровня самого первого марио.
Ещё я атмегу8 ( не пердуино) ковырял маленько, пытаюсь собрать свой геймпад, прошивка под нее готовая есть, но тут у меня уже проблемы с пайкой. Но в идеале хотелось бы понимать и редактировать эти прошивки для атмеги.
Сам я с программированием не связан. По книге для С из оп-поста как-то дошел до функций, проблем с пониманием не было.
>>608901
Не, мне миллионы не нужны, тысяч 40-50 было бы заебись получать.
Если тебе нужна десктопная программа как результат, то посмотри на шарп и питон. Особенно, если это бот для твитча. Байтоёбские возможности си тут мягко говоря не нужны - текст или интерфейс для программы намного менее запарно в чём-то высокоуровневом обрабатывается. Такое на си есть смысл писать, только если тебе сам процесс очень нравится и ты готов потратить достаточно времени на это.
Тому, что вакансии С на 40-50 есть я уверен, а вот что бы на них кто то работал - нет.
После получения всех знаний что необходимы на подобную вакансию - ты сьебешь куда нибудь за 100+.
С это не про ботов, платформеры и дрочение текстовых файлов. Это как хуй знает, пинцетом землю копать.
Ты можешь, но там лопата если что лежит.
С# это же тот же JS не?
Вроде видел что на питонах ботов делают для твича. Но питон это вообще полноценный язык или на нем только скрипты можно хуячить? На питоне игры кто-нибудь вообще делает?
А на си графический интерфейс вообще можно прикрутить или только в консольке ебаться?
Я ещё думаю о том какой язык лучше всего подходит для начального обучения программированию. Начинать с того же с++ мне кажется хуевой идеей.
Ну и байтоебить на си пока я читал книгу мне в принципе понравилось.
>
>А на си графический интерфейс вообще можно прикрутить или только в консольке ебаться?
Собственно,
http://www.winprog.org/tutorial/
https://developer.gnome.org/gtk3/stable/index.html
>Ну и игры на нем вроде как инди студии делают иногда.
Инди-студии делают игры на конструкторах вроде уеча и юнити, либо на более легковесных аналогах.
Геймдев еще в конце 90х перелез на кресты, даже на соснулях - последним из могикан был кармак, причем порт последних написанных им сорцов третьей кваки тебе скинули выше, уже думец 3 кармак с начала нулевых писал уже на кривых, но крестах.
>Неужели работа на си - это только поддержка старого говна?
нет, еще написание дров, библиотек-ускоряшек когда наждо ускорить скриптцо, кода для микроконтроллеров.
Т.е. писать дюпроги для атмеги - это только си?
А что насчёт остального?
Как жить без статика в С89?
Если в разных С файлах будут переменные с одинаковыми именнами, меня не озалупит?
Есть несколько общих вопросов по исследовнию сишных библиотек для проекта. Исследуемая библиотека BPF
1. Как измерять производительность компиляции (чем и в каких единицах измерения)
2. Как затестить скорость отброса пакетов, если они будут генерироваться на той же машине
3. Существуют ли готовые решения для тестов самого BPF (например, для сравнения скорости работы кода JIT и прекомпилированого)
4. tcpdump -d выводит именно bpf bytecode или попросту похожий assembler-like код?
Не бейте сильно если выдал что-то крайне тупое
https://habr.com/ru/post/66562/ пруф
Он интерпритируемый. Каждый раз когда запускаешь код на питоне, сначала он интерпритируется в другие ЯП (обычно си, на сколько знаю), после чего уже куски си, которые друг к другу никто не оптимизировал, компилятся в машинный код, который уже выполняется машиной
Самое базовое - Byte of Python
Довольно маленькая и разжеванная книга, но воспринимается на ура
Буквально за пол дня можно совершенно свободно владеть общим синтаксисом
Она кстати совершенно свободная к распространению
http://wombat.org.ua/AByteOfPython/AByteofPythonRussian-2.01.pdf
>это вообще полноценный язык или на нем только скрипты можно хуячить?
Ну так. Не знаю почему ты спрашиваешь в си-треде, но питон интерпретируемый и он тормознее си в 20-200 раз на любом коде, и потому сложную игру реального времени на нём писать не очень. Говорят есть всякие "компиляторы", которые совсем медленный скрипт в более-менее резвый байт-код уровня шарпа превращают, но никогда не пробовал и врать не хочу. Возможность прикрутить интерфейс есть, как и в си.
Если ты хочешь игру - то идеальная комбинация, это написать игровую механику на с++, а вот все менюшки, справки и прочее выполнить на каком-нибудь лёгком скриптованном языке - что интерфейс не был прибит гвоздями и его можно было менять без особых проблем. Если у тебя визуальная новелла или сапёр то всего этого не требуется, конечно, и вряд ли ты будешь делать такую игру в ближайщие два года, где без с++ не разобраться. С си без крестов ещё раз повторю - имеет смысл писать игру на си, только если тебе очень нравится сам процесс, а игра или какой-то другой результат даже приблизительно тебя не интересует.
>Начинать с того же с++ мне кажется хуевой идеей.
По сравнению с си там чуть-чуть ниже порог вхождения и намного больше пространства для изучения. Можно изучить только си, и потом писать на с++ взяв от плюсов только стандартные контейнеры, ссылки и вызов методов у структур — фактически ты всё ещё будешь писать на си (и твой код можно будет переделать в си-код почти без изменений), но очень сильно облегчишь свои страдания синтаксическим сахаром в виде вызова методов и ссылок.
Питон имеет ещё более низких порог вхождения (его просто нет по сравнению с си) - но он очень многоуровневый и тоже имеет громадное пространство для изучения, порог то низкий — но во что ты входишь? Вникнуть в питон и использовать все его возможности сложнее, чем сделать это с си/си++. Это лишь мой субъективный опыт. При этом изучив питон использовать си++ ты едва-едва сможешь и будешь писать не оптимальный код, пытаясь воплотить идеи питона там, где этого не требуется — а изучив си++ потом можно без какой-либо длительной адаптации на среднем уровне использовать питон.
>это вообще полноценный язык или на нем только скрипты можно хуячить?
Ну так. Не знаю почему ты спрашиваешь в си-треде, но питон интерпретируемый и он тормознее си в 20-200 раз на любом коде, и потому сложную игру реального времени на нём писать не очень. Говорят есть всякие "компиляторы", которые совсем медленный скрипт в более-менее резвый байт-код уровня шарпа превращают, но никогда не пробовал и врать не хочу. Возможность прикрутить интерфейс есть, как и в си.
Если ты хочешь игру - то идеальная комбинация, это написать игровую механику на с++, а вот все менюшки, справки и прочее выполнить на каком-нибудь лёгком скриптованном языке - что интерфейс не был прибит гвоздями и его можно было менять без особых проблем. Если у тебя визуальная новелла или сапёр то всего этого не требуется, конечно, и вряд ли ты будешь делать такую игру в ближайщие два года, где без с++ не разобраться. С си без крестов ещё раз повторю - имеет смысл писать игру на си, только если тебе очень нравится сам процесс, а игра или какой-то другой результат даже приблизительно тебя не интересует.
>Начинать с того же с++ мне кажется хуевой идеей.
По сравнению с си там чуть-чуть ниже порог вхождения и намного больше пространства для изучения. Можно изучить только си, и потом писать на с++ взяв от плюсов только стандартные контейнеры, ссылки и вызов методов у структур — фактически ты всё ещё будешь писать на си (и твой код можно будет переделать в си-код почти без изменений), но очень сильно облегчишь свои страдания синтаксическим сахаром в виде вызова методов и ссылок.
Питон имеет ещё более низких порог вхождения (его просто нет по сравнению с си) - но он очень многоуровневый и тоже имеет громадное пространство для изучения, порог то низкий — но во что ты входишь? Вникнуть в питон и использовать все его возможности сложнее, чем сделать это с си/си++. Это лишь мой субъективный опыт. При этом изучив питон использовать си++ ты едва-едва сможешь и будешь писать не оптимальный код, пытаясь воплотить идеи питона там, где этого не требуется — а изучив си++ потом можно без какой-либо длительной адаптации на среднем уровне использовать питон.
>Начинать с того же с++ мне кажется хуевой идеей.
>>По сравнению с си там чуть-чуть ниже порог вхождения
У этого указатель сорвало, переинициализируйте.
Ты без статика да ещё и с глобальными переменными? Тут два варинта анон, ты либо кармак, либо долбоёб. Выбирай.
> куски си, которые друг к другу никто не оптимизировал
> компилятся в машинный код
> питон
Лолшто?
то есть один цикл While прошёл от и до == 1 кадр на мониторе компьютера сформирован. за 1 секунду while совершается от 25 до 45 раз в среднем. в зависимости от того кол-ва требуемых для выполнения операций в цикле.
вот стоишь на улице допустим просто 40 кадров, сделал выстрел пистолетом, загрузился звук, прошло движение, появилась дырка на объекте кудаа пуля попала уже в цикле действий было больше чем когда ты на улице был и получилось 30 кадров.
ну образно говоря. скажите, пожалуйста, я правильно думаю? если что я ньюфаня. просто представил как бы я это закодил если бы у меня такая задача была.
> ну образно говоря. скажите, пожалуйста, я правильно думаю?
Образно говоря, ты правильно думаешь.
> прошло движение
Движение "само" получается. Ты рисуешь пулю, говоришь, куда ей и с какой скоростью двигаться. Функция обновления игрового мира двигает ее куда надо, в зависимости от того, сколько прошло времени с предыдущего апдейта. Функция отрисовки рисует пулю по вычисленным координатам.
> уже в цикле действий было больше чем когда ты на улице был и получилось 30 кадров
Если движок и железо не совсем говно, то у тебя действий гораздо меньше, чем нужно чтобы заполнить 1000 / 30 = 33 мс апдейтами мира и рендером. Фпс дропаться будет только в сложных сценах.
А что насчёт работы для питона?
Если сейчас все игры делают на с++, то имеет смысл учить сперва С, а уже потом с++? Я как-то начинал сперва книжку по с++, потом сразу же по с, мешал команды из обоих и это все нормально работало.
>мешал команды
Шизло, плиз, посиди в ридонли сначала и желательно не тут, а в книжках
Командир межрасового батальона блядь.
Да, пока у тебя не выключена синхронизация.
понял. спасибо, анон. ну мне просто ради интереса чтобы поверхностно знать как это всё работает.
> Это ведь неправда, у функций scope глобальный и распространяется на весь файл, как и у переменных с extern, почему он так пишет, типа стандарт старый?
В с89 скоуп на "строки выше".
Именно поэтому в языке есть прототипы функций.
Чем "на строки выше" отличается от "на весь файл"? Как это связано с прототипами функций?
>сейчас все игры делают на с++,
Сейчас все игры делают на готовых конструкторах, учиться нкужно или сисярпу, если юнька или тыкать мышью если уеч.
Впрочем да, кресты в уече тоже есть - на них тяжелую логику пишут, когда на блюпринтах совсем пизда.
Основная проблема геймдева, из которой так же возникает его особенность -
ГЕЙМДЕВ - ЭТО НЕ РАЗРАБОТКА СОФТА, ГЕЙМДЕВ ЭТО РАЗРАБОТКА КИНЦА И РАБОТАЕТ ГЕЙМДЕВ КОНТОРА КАК КАКАЯ СЕРИАЛОСТУДИЯ ИЛИ КИНОСТУДИЯ А НЕ КАК СОФТОВАЯ ГАЛЕРА.
В геймдеве 90% всего работы это арт-составляющая, на всех стадиях поиска идей, прототипирования, арт-дизайна, контента. Непосредственно механика и обслуживающий её код (скриптинг, двигло и прочее) - это процентов так 10.
>Чем "на строки выше" отличается от "на весь файл"? Как это связано с прототипами функций?
Тем, что часть файла строчками ниже того места где ты дергаешь функцию суть есть аут оф скоуп.
ну да, главное дизайн надрочить, а кодер это только всё оживляет и делает так чтобы оно двигалось.
Под "дёргать" ты имеешь в виду вызов функции? Но речь идёт не о вызове, а об определении
Ага именно поэтому блядь на всякие дрочильни, которые разрабатывают не 500 человек, патчи, в которых всем понятно что и как, могут выходить годами.
Хуйня все это. Как раз арт и все творчество очень хорошо параллелится.
100 дизайнеров нарисуют 100 моделек в 10 раз быстрее чем 10 дизайнеров.
Напишут ли 100 разрабов движок в 10 раз быстрее, чем 10 разрабов? Да нихуя не факт. Коду постоянно надо успевать за меняющимися концептами и идеями, при этом не залезая в технический долг. Дохуя кто не справляется.
2x жопочтец.
Я спрашивал че будет с одинаковыми именнами переменных, без статика. Т.к. перепутал статик с инлайном.
Статик был в С89, инлайн нет.
причём здесь вхождения символа когда там просят проверку на синтаксис. чтобы скобки соотвествовали и прочее.
А программы ты как пишешь? Не символами?
На самом деле программа не сложная, просто подзаебаться придётся немножко пока думать над кодом будешь. Здесь очень много проверок if нужно будет.
Выглядит как классическая задача на стека:
1)Реализуй стек
2)Пробегись по тексту:
Если нашел левую скобку - пуш в стек
Если правую - поп и сравнение
Тогда предлагаю пропустить эту задачу.
а вообще, брошурка Полякова по си мне зашла гораздо лучше k&r
я её сделаю просто с учётом тех функций языка которые мне уже известны по книге. я уже гуглил решения этой задачи они там через switch делали ещё как-то заумно, к моменту этой задачи о таких инструментах читателю ещё неизвестно.
а что там интересного? натыкаю туда кучу is-else вот и вся программа. ну ладно, скину если уж хочешь.
где через switch?
Завидую тебе, анон. Ты уже это прошёл, а я только в самом начале. Ну как вначале, у меня уже основа кода есть, уже в каких-то простых случаях ошибки детектятся.
Много перечислено книг, но в основном все о самом языке. Есть книги по разработке? Как Си применять то вообще? Как писать кроссплатформенный код? Как писать параллельный, конкурентный, асинхронный код? Как взаимодействовать с ОС? Какие есть незаменимые либы, кроме стандартной библиотеки? Какие есть инструменты? Много вопросов имеется. Си вроде один из самых старых языков, но информации о том как его использовать в реальной жизни очень мало.
ща бы в си нестаднартные либрари подключать, вот это маня, ой манюна. возвращайся в свои джавы, питоны, пыхи неча здесь тебе ловить. какая разработка на си? мань, язык годый, но в современных реалиях его в основном используют для написания драйверов.
Ты работаешь или как?
>ща бы в си нестаднартные либрари подключать
А евент либы, libuv, libevent, etc? Щас бы слушать твои маняфантазии
Просто некоторая область памяти вместе с указателем на эту область (точнее на её часть). Обычно используется для субрутин (точнее выхода из них).
Выглядит это примерно так:
sp=#1111 (это stack pointer, он хранит значение ячейки памяти в которую будет проводиться запись)
pc=0 (указатель на память с которой мы работаем прямо сейчас)
Далее инструкции (начиная с #0000)
0000 MOV $13, A (просто инструкция)
0001 CALL #1C56 (вызов субрутины по адресу 1С56, в этот момент число 0001 (наш pc) записывается в память по адресу 1111, а sp=1112)
...
1С56 ADD B, A (просто инструкция, в этот момент pc=1C56)
1C57 RET (команда которой заканчивается любая субрутина, pc=верхнее число в стеке т.е. 0001)
Субрутина - это, считай, функция.
Сама реализация отличается от процессора к процессору: где-то стэк идет вниз, где-то вверх итп). Пример выше не относится к какому-то конкретному процу.
Не знаю, правда, как у современных amr'ов с х86, но раньше было так. Не думаю что они поменяли реализацию, но поправьте если что.
>Просто некоторая область памяти вместе с указателем на эту область
Где? В кэше какого-то уровня? Не в оперативке же?
Нет "в процессоре" никакого стека. Это просто кусок оперативки:
int stack[100];
// Стек у нас full descending:
// descending: растет вниз, в младшим адресам по историческим причинам;
// full: sp указывает на ячейку, содержащую последнее воткнутое значение, а не на пустую ячейку, как в empty-стеках.
int ∗sp = stack + 100;
void push(int value) { ∗(--sp) = value; }
int pop(void) { return ∗(sp++); }
Иногда (далеко не всегда) у процессора есть какие-то инструкции, которые позволяют делать вот эти push/pop одной командой. И часто есть конкретный регистр, которых хранит sp. В x86 есть еще немного сахарка (да, сахарок на уровне машинного кода) для вложенных стекфреймов, но его никто не использует.
Почему я ошибаюсь? Я же написал, что:
> И часто есть конкретный регистр, которых хранит sp.
Но в том же ARM, если ты не используешь систему команд Thumb, ты можешь использовать для указатестека любой регистр, можешь даже несколько параллельных стеков иметь, потому что там работа со стеком осуществляется обычными mov и ldm/stm (load/store multiple), в которых ты можешь адресоваться относительно любого регистра. Сам стек при этом лежит в обычной, адресуемой памяти. Да, в том же ARM можно положить стек в TCM, это такой небольшой кусок SRAM, который расположен в процессоре, но опять же: 1) с точки зрения программиста разницы с обычной памятью нет; 2) можно и не ложить стек туда, этой памяти мало, поэтому туда обычно обработчики прерываний суют.
> Так почему ты пишешь, что в процессоре нет стека?
Потому что в регистр в лучшем случае влезает 64 бита (если он не SIMD), для стека это как-то маловато, нет? Так что я тоже начинаю склоняться к тому, что это
> троллинг тупостью?
Кароч, на тебе линк: https://www.ixbt.com/cpu/cpu-digest-2009.shtml
сам не читал, но вроде годно и пиздуй нахуй, нефиг засирать си тредик.
Чего ты мне голову морочишь? Я понятия не имею какой размер регистра. Тем более не знаю размер стека. С чего ты взял кстати, что 64 бита мало для стека?
>>610756
>Кароч, на тебе линк: https://www.ixbt.com/cpu/cpu-digest-2009.shtml
Там про стек ни слова
>пиздуй нахуй
Уёбок чсвшный
Сначала внимательно ознакомься с архитектурой, а затем вернись, и перечитай что тебе ответили тут.
Ты сам не можешь ответить есть стек или нет и где он находится. И ты мне советуешь ознакомиться с архитектурой? Вот это настоящий троллинг тупостью. Скажи, а сишники все такие чсвшные? Я с вас в шоке, вы даже не знаете собственного инструмента. Не ты ли мне писал, что сторонние либы использовать зашквар? Хотя какая разница, вы тут все одного поля ягоды.
Этот питонист порвался, несите нового.
А вообще, тебе уже ответили. Повторяю:
Есть старые процессоры (серии 8080 итп), в них нет ярого выделения оперативки, про них можно сказать что стек находится "в процессоре"
А есть более современные (arm итп.), у них, со слов другого анона (а причин не доверять ему я не вижу) есть такое разделение, и более выгодным получается хранить стек "вне процессора" (причины он тоже описал)
> Есть старые процессоры (серии 8080 итп), в них нет ярого выделения оперативки
Чего? В 8080 стек в оперативке, как и везде. Регистр SP используется под указатель стека.
Тфьу, модуль отдельный, модуль.
У процессора нет стека, у него есть регистр SP - stack pointer, т.е указатель на ту область, которую ОС/программист зарезервировал под стек. Можно выделить память, настроить доступ страниц и создать свой стек, например.
У тебя в ОС пара тысяч потоков обычно (естественно, не все выполняются, большинство висит на IO). Каждому нужен стек. Внимание, вопрос: сколько памяти должно быть в процессоре, чтобы разместить стеки там, если учесть, что одному потоку в современной ОС обычно требуется около 50-100к?
>>610816
Тебе давали микросхему, у нее ноги для адресной шины/шины данных, а память ты припаиваешь внешнюю, отдельным жирным устройством. Откуда там внутренняя-то?
>>у нее ноги для шины данных
Даже загуглил, и правда.
последний раз имел с ним дело в виде сишной структуры, там память шла в куче с регистрами... шиза наверное
Ладно, пойду я отсюда, пока еще кого не обманул.
Ссыль кста на стек: https://ru.wikipedia.org/wiki/Стек_вызовов
>У тебя в ОС пара тысяч потоков обычно
Какие тысячи? У меня в линуксе не более 100 процессов висит.
>Внимание, вопрос: сколько памяти должно быть в процессоре, чтобы разместить стеки там, если учесть, что одному потоку в современной ОС обычно требуется около 50-100к?
Откуда цифры 50-100 Кбайт? Некоторые виртуальные машины выделяют под процесс всего 2,5 Кбайта, например BEAM (Эрланг).
> Какие тысячи?
Взял с потолка, имея в виду сервера, очевидно же. На клиенте меньше, на винде с двумя ядрами чуть больше 500 потоков (это семерка, наверняка в десятке больше). В серверных приложениях с асинхронщиной традиционно делают по потоку на ядро минимум, там тоже будет больше.
> Откуда цифры 50-100 Кбайт?
Выбирал когда-то, сколько давать потокам в своих приложениях. Можешь попробовать пройти по всем потокам в системе, посмотреть на rsp относительно верхушки стека, посчитать среднее и рассказать нам.
> некоторые виртуальные машины выделяют под процесс
И ничего не хранят в системном стеке, у них все свое, так?
Рандомно потыкал вручную (да, опять винда): эксплорер - 60K, нотепад - 24К, севензип 40К, отродья хромиума - потоки от 4К до 32К, торрент - от 4К до мегабайта, рандомное говно на дотнете - куча потоков, у каждого 40-50К. Это все commit (с оглядкой на working set), т.е., это тот размер, который используются реально. Окей, получается, что скорее 50К, чем 100.
>На клиенте меньше, на винде с двумя ядрами чуть больше 500 потоков (это семерка, наверняка в десятке больше).
Где ты вообще потоки видишь? Диспетчер задач в Windows, как и системный монитор в Линукс показывают процессы, а не потоки.
>И ничего не хранят в системном стеке, у них все свое, так?
Не понял о чем ты. При запуске "управляемого кода" в любом случае создается процесс ОС.
>Какие тысячи?
Он почти прав.
Виндоус 10, у меня открыты - браузер с 6 вкладками борды (примерно 100 потоков из-за ебанутой многопроцессной системы - голову бы открутил тому кто это придумал), дискорд (около 60 потоков по тем же причинам), питон (4 потока), фигня в фоне для ram-дисков (2 потока), explorer.exe (76 потоков). Всё остальное - какая-то неведомая ебола в системе. При этом у меня отключены все службы обновления, службы телефонии и куча других мусорных служб, с которыми там бы ещё сотни четыре набежало.
Не могу удержаться и прикреплю вторую картинку, просто чтобы линуксоиды увидели этот (это ещё не весь список) ужас.
>Виндоус 10, у меня открыты - браузер с 6 вкладками борды (примерно 100 потоков из-за ебанутой многопроцессной системы - голову бы открутил тому кто это придумал), дискорд (около 60 потоков по тем же причинам), питон (4 потока), фигня в фоне для ram-дисков (2 потока), explorer.exe (76 потоков).
Ясно понятно. Хорошо что у меня Линукс. Там такого и близко нет. 40-50 пользовательских процессов + столько же системных.
Я же написал. Выделяешь блок памяти, настраиваешь доступ к страницам (rw/x/g), добавляешь обработчик, меняешь контекст потока и готово. При должном желании получится полноценный почти пользовательский стек.
Процесс и поток это одно и тоже в линуксах?
Я слышал там другое внутреннее устройство потоков, с куда более лёгким переключением между ними, чем в виндах. А процессы более-менее схожи.
> Не понял о чем ты. При запуске "управляемого кода" в любом случае создается процесс ОС.
Процесс создается, но если ты сделал в скрипте x = my_script_func(), используется ли для этого вызова "обычный" стек, или у тебя в struct vm_context { uintptr_t vm_callstack[NUM]; }, а все объекты, включая вот эту vm_context - в куче. В таком случае стек будет использовать только диспетчер вм, а ему совсем немного нужно - ну будет там вложенность 3-4 вызова от силы.
>>610953
Да в большинстве случае достаточно просто rsp поменять на куда-угодно. Можно даже в "реальном" стеке выделить кусок, так корутины в сишке делают.
>>610950
> 40-50 пользовательских процессов
А ты потоки-то посчитал? ps -eLf
>>610955
> Я слышал там другое внутреннее устройство потоков, с куда более лёгким переключением между ними
Там фактически нет разницы между потоком и процессом. Отличия от процесса в основном в том, что создается поток через clone(), а не через fork() и в том, что адресное пространство потоков - общее.
> с куда более лёгким переключением между ними, чем в виндах
Да в виндах уже UMS (user-mode scheduling) завезли, и давно. Хуй знает, насколько оно там быстрее.
>Выделяешь блок памяти, настраиваешь доступ к страницам (rw/x/g), добавляешь обработчик, меняешь контекст потока и готово. При должном желании получится полноценный почти пользовательский стек.
В Си разве такие возможность в язык встроены? Это наверное api ОС позволяет такое делать? Где можно об этом почитать?
>Там фактически нет разницы между потоком и процессом.
Как это нет. Множество потоков могут принадлежать одному процессу. Но не наоборот.
> Множество потоков могут принадлежать одному процессу
Это детали. Как и про доставку сигналов, про execve и прочие тонкости. В винде отличия гораздо сильнее: процесс не может выполнять код, ему нечем.
>>611107
> В Си разве такие возможность в язык встроены?
Частично: есть setjmp/longjmp, они меняют в том числе и указатель стека, но по стандарту они непрозрачные (хотя на конкретной ОС ты можешь попатчить jmp_buf сам). Можно дергать всякие SetThreadContext в винде (для своего потока можно через SEH/VEH поменять, я кидал пример в соседний тред >>1597614 →), setcontext в nix (только оно deprecated). Но лучше всего написать реализацию на ассемблере самому, там реально пара инструкций. Это про переключение стеков. А что касается:
> Выделяешь блок памяти, настраиваешь доступ к страницам
Это ты просишь у ОС. Смотри на mprotect/mmap в nix и на VirtualProtect/VirtualAlloc в винде, например.
> Где можно об этом почитать?
В мануале по процессору, в описании ABI твоей ОС.
>процесс не может выполнять код, ему нечем
Шта блять? Может ты и прав, но как я узнаю об этом? Где это написано?
Ну он прав, процесс это всего лишь среда, которая имеет собственное адресное пространство, единица выполнения это поток.
https://docs.microsoft.com/en-us/windows/win32/procthread/about-processes-and-threads
> как я узнаю об этом
Windows Internals расскажет тебе, что есть системная структура KPROCESS, что в KPROCESS есть linked list c потоками (KTHREAD), в потоках сохраняется контекст CPU И все остальное, что нужно выполняющемуся коду, и что планировщик, естественно, работает именно с KTHREAD. Ты можешь подумать, что ничего не мешает тебе иметь KPROCESS с пустым списком KTHREAD. Дальше ты можешь посмотреть WRK или какую-нибудь книжку/статью про Native API и узнать, что ZwCreateProcess и более низкоуровневые функции сами по себе не создают никаких потоков, ну и затестить: собрать https://pastebin.com/raw/axHPfjFn и посмотрев в любом таскменеджере, увидеть, что потоков у тебя ноль, и process times тоже по нулям, и переключений контекста нет (пикрелейтед), потому что планировать нечего. Если что, suspended процессу выставил не я.
В линуксе все по-другому. Планировщик там оперирует тасками (struct task_struct, фактически - процессами), именно в таске лежит сохраненный контекст CPU, всякие там стеки и прочие флаги, и главное, именно ему назначается тот самый pid (process id), который ты видишь в листинге ps. В линуксе контекст неотделим от процесса, поэтому в линуксе ты не можешь сделать поток без процесса, процесс без потока и все такое прочее.
Охуенно, я про такие извращения минувших дней даже не знал. Спасибо.
Ты винду в пример приводишь, как будто это эталон какой то. У меня вот линукс стоит.
> Ты винду в пример приводишь, как будто это эталон какой то. У меня вот линукс стоит.
Ядро NT проектировалось с учетом ошибок UNIX. Ядро Linux было изначально ограничено необходимостью реализации POSIX. К тому же, оно изначально никак не проектировалось по сути, а писалось, как получится.
Стек в ram, указатель на память в регистре
>Ядро NT проектировалось с учетом ошибок UNIX.
Угу, проектировали проектировали, да не выпроектировали. Совместимость с POSIX неполная, костыльная. Из-за этого нельзя просто так взять, и установить какой нибудь язык программирования.
>примерно 100 потоков из-за ебанутой многопроцессной системы - голову бы открутил тому кто это придумал
Без этой многопроцессной системы у нас был фуррифокс, который вис со всеми открытыми вкладками, если хотя бы одна зависла, например из за васи шутника написавшего бесконечный цикл на JS
Опера не висла. А там были отдельные потоки на вкладку, а не процессы.
> Совместимость с POSIX неполная, костыльная
Это плюс, а не минус. POSIX основан на принципах, которые не выдержали столкновения с жестокой реальностью. Например, ты не можешь просто взять и написать сколько-нибудь быстрое кроссплатформенное сетевое приложение - в линуксе свои костыли, во фре свои, в маке третьи.
> нельзя просто так взять, и установить какой нибудь язык программирования
Ты хотел сказать компилятор. Нет, не из-за этого.
> Ну давай пособирай Окамловские пакеты под винду.
Так это их проблемы, что они не могут писать кроссплатформенный код и не завезли поддержку винды.
Компилятор Окамла работает на винде. Но проблемы могут возникнуть при компиляции пакетов.
for (int i = 0; 1; ++i)
printf("E\n");
вот здесь что сперва происходит printf или ++i. По-моему printf я так понял что ++i делается после каждого выполнения тела цикла. Я прав?
printf. Инкрементация пред-какая-то (забыл название) работает только для выражений, expressions. По логике конструкции for, ++i выполняется всегда после 1 итерации цикла.
наоборот всмысле.
systemd - говно ебаное, автор выебистый sjw петух на зарплате у RedHat, который имеет славу писать залупу и по слухам вся эта шелупонь с CoC для того, чтобы повнедрять уязвимости в kernel
Это копия, сохраненная 21 апреля 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.