Вы видите копию треда, сохраненную 31 августа 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 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 помогает читать сложные сишные декларации.
Прошлые треды:
- №53: http://arhivach.ng/thread/529929/
- №54: http://arhivach.ng/thread/535256/
- №55: http://arhivach.ng/thread/543511/ >>1634080 (OP)
Так вон же он, черновик в шапке. Будут атрибуты и по мелочи еще. Ничего из того, что хотелось бы получить.
Скорость. Сделайте хеллоуворлд в пять раз меньше, перепишите библиотеки на ассемблере.
Это не входит в стандарт. Алсо, glib даже на стандарт хуй клали, и только в 2.28 завезли <thread.h>
>и только в 2.28 завезли <thread.h>
потому что оно не нужно в стандарте.
>на стандарт хуй клали
это опциональная фича. всё по стандарту.
> glib
glibc
>>61238
http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2386.pdf версия с диффами (не уверен, что последняя), список изменений в самом начале.
Не работаю, не платят - хорошо.
Есть какой-нибудь путь, писать и тестировать код локально на маке с видюхой Radeon, а потом без лишней головной боли запустить тоже самое в датацентре с видюхой Nvidia на Linux?
>Abstract
Дальше не читал. Отвлеченное пиздабольство вместо технической документации не нужно.
> Есть кто-нибудь, кто байтоебит на GPU?
Ты один и тот же?
Общее АПИ юзай, вопросы с пакетами решай шэллом или просто интересуйся заранее.
Код парсинга прямо в main и складывать в локальные переменные main()?
Вообще, слышал, что функция должна делать предельно мало и иметь мало переменных, но судя по всему main() исключение в основном...
Мне вообще не хватает мудрости на тему что должна делать main().
Разобрался, спасибо.
Теперь интересует сугубо практический вопрос.
Вижу два вара для вывода ошибок в простой (5-10 CLI-параметров) программы:
- написать большую функцию, много массивов со стандартными сообщениями. В теории обработка не нужна, каждая ошибка - смерть проги. Функцию в отдельный хедер, вызывать её всегда, если результат malloc NULL и прочее, прочее.
- просто макрос/мини-функция в main() с чем-то из glibc типа perror/strerror + своя обработка ошибок при парсинге аргументов
Сразу хочу сказать, что источники ошибок либо в аргументах программы, либо функции glibc.
Переменные вне функции - statiс, должны либо нулями инициализироваться, либо значениями, известными во время компиляции.
Если ты хочешь разово инициализировать переменную в рантайме, используй static в функции.
Просто работаешь напрямую с клавиатурой, или какой-то фреймворк для этого ищешь. До этого с клавиатурой работал терминал, а ты у него только готовый поток символов брал.
у кнопки два события (event) press_down press_up
гуглишь на чем пишешь как это у тебя реализовано
ну а зачем под линукс что-то писать? чтобы чесать чсв среди задротов и школоты. денег не заработаешь если будешь опенсорсом заниматься, всё в win упирается. тёти сраки, малолетние геймеры, студенты и прочие личности на линуксе не сидят
Подходит, не троллинг.
Язык несильно поменялся, книга лаконичная и учит языку без навязывания стиля.
для совсем ньюфагов которые вообще ничего не знают о погромировании не подходит. подходит если ты допустим писал на каком-нибудь питоне, потом начал си учить вот тогда подходит. если ты уже знаешь что такое рекурсии, массивы и т.д.
4 вопроса тут у препода возникло, хочу сдать пока есть возможность.
1. Что передается в аргументах функции main()? ( argc / argv там в main у меня )
2. Значение, которое возвращается из функции main(). Можно его каким-то образом получить там, откуда была запущена программа (например, в терминале)?
3. С помощью каких функций стандартной библиотеки можно преобразовать строки в числа? Перечислить как минимум три группы функций.
4. Чем статическое выделение памяти в программе на C отличается от динамического? Привеcти примеры
Не успел просто освоить Си, восстановился недавно.
1. Что хочешь то и передаётся, можешь ничего не передавать и поставить туда void впринципе всё как у всех функций.
2. Да, main всегда возвращает что-то в окружение, даже если ты не поставишь return в коде он вернёт какой-то код.
3. Блин, усложнил. Пришлось открыть книгу k&r и вспоминать. Это atoi из библиотеки stdlib.h по поводу трёх групп сам ищи в этот бессмысленный и беспонтовый вузиковский дроч углубляться смысла нет, ибо если ты даже выучишь то если не будешь использовать это то забудешь.
4. Ну преполагаю что при статическом выдлении памяти в си выделяется конкертный фиксированный размер памяти, а при динамическом память может расширяться по мере необходимости.
Но опять же это всё не факт, т.к. смотри строки ниже
учу си с 10-го января 2020, 22 лвл, птушное образование, 2,5 года сижу на мамкиной шее из дома не выхожу
хотя по поводу третьего я не понял про группы, но есть ещё 2 функции которые переводят в числа символы это atof и atol как там просто разные выходные типы есть long, int и double надеюсь ты это имел в виду
>Да, main всегда возвращает что-то в окружение, даже если ты не поставишь return в коде он вернёт какой-то код.
А получить то его как?
вот именно.
4. Статическая выделяется во время компиляции, хранится в стеке, не может быть изменена после компиляции.
Динамическая выделяется во время выполнения, хранится в куче, может изменять размер во время выполнения.
int a; // статическая
int a = (int) malloc(sizeof(int)); // динамическая
ебаная двачеразметка съела звездочки
>Норм практика?
нет. смысл в этом есть только на старых и ограниченных системах.
главная проблема, что глобальные переменные ухудшают понимание программы.
>главная проблема, что глобальные переменные ухудшают понимание программы.
Лол, поаккуратнее, ты очень близок к призыву из Рльеха пердоли-байтоёба с его "РРРЯЯ ПИДОРЫ-ФУНКЦИОНАЛЬЩИКИ НЕ ХОТЯТ В СИШЕЧКЕ ГОВНО ЖРАТЬ. ДИДЫ ЖРАЛИ И МЫ БУДЕМ ЖРАТЬ. ТОЛЬКО ГЛОБАЛЬНЫЕ ПЕРЕМЕННЫЕ. ТОЛЬОК ХАРДКОР"
На самом деле сама программа ухудшает понимание программы. Все функции сделаны под другие функции, они не переносимы, они больше не вызовутся ниоткуда. Для крестов проблема звучала бы: использовать синглтон, или нет.
На самом деле проблема звучит так: дегенераты навкатывались в программирование и хотят чтобы язык за них писал хорошие понятные программы, ведь сами не могут, да и не хотят.
А кого ты собрался брать в расчёт в С-тхреаде?
Ломаю голову над тем, где чистить память под строку, которую возвращает создающая её функция. Если слепо смотреть на функцию, можно пропустить этот момент. Если использовать эту функцию, нужно чистить строку после использования. Если строка остаётся до конца использования программы, нужно чистить это при sigterm, чтобы не было ничего неучтённого.
Всё это неудобно.
Альтенативно можно инициализировать буфер char* x[MAX] = {}; и использовать только его либо внутри функции, либо извне, но во втором случае, нужно передавать дополнительные параметры в виде размера, а это усложняет код
Короче придумал.
В функции локально массив x[MAX] = {0};
Функция возвращает std::string, но на самом деле char*
Я беру новый std::string и в него вызываю функцию, инициализируя.
у меня есть некоторые сомнения, как лучше инициализировать в этой ситуации. Мож лучше таки memset-ом, вдруг массив инициализируется только по первому вызову
Крч хуй его знает чё там внутри происходит, если у меня в программах будут утечки памяти, мне похуй
>The c_str() result becomes invalid if the std::string is destroyed or if a non-const member function of the string is called. So, usually you will want to make a copy of it if you need to keep it around.
Хмм.
>free
>A block of memory previously allocated by a call to malloc, calloc or realloc is deallocated, making it available again for further allocations.
Хмм.
кстати в продолжении темы. я мельком пролистал наса-код-стайл. они предлагают глобальные переменные объявлять extern'ом в начале каждой функции их использующих. но что делать, если ты назначаешь переменным адреса сам, типа так:
#define gl_screen_status (@(volatile uchar@)0xD800)
#define gl_sprites_left (@(volatile uchar@)0xD801)
#define gl_task_rem (@(volatile struct dlist_head@)(0xD802))
#define gl_task_add (@(volatile struct dlist_head@) \
(0xD802 + sizeof(struct dlist_head)))
...
это же единственный стандартный способ это сделать?
Как линуксовый форк дружит с мультитредингом?
Допустим, я хочу запустить N отдельных процессов (1 батя у которого N сынок-корзинок), чтобы не было зомби-процессов, мне в куске батиного кода нужно от каждого сына ждать сигнал с помощью сисколла wait(или waitpid), проблема в том, что он ждет каждый процесс по отдельности (сначала сын 1 завершился, потом сын 2, сын 3 и т.п.), а я хочу расфоркаться и чтобы эти N форков ебашили параллельно, а wait был типа асинхронным. Это возможно?
Ты на что делаешь free? У тебя нет ничего на куче, начнем с этого. Ты в курсе как отличаются стэк и куча? Знаешь что такое malloc/calloc?
Бляха-муха, так я ж говорю
Я не хочу ситуацию, где я с расфорканным хлебалом жду каждого сына по отдельности, я хочу чтобы расфорканные процессы-сыновья выполнялись параллельно. То бишь, чтобы цпу прыгал между ними, выполняя по сути все N процессов-сыновей параллельно.
Так он так и делает? Это отдельные процессы, когда ты их отправил выполняться, ос между ними будет переключаться, а родитель пока ждёт.
Нет, братан.
Батя будет ждать каждый процесс по отдельности через wait, я тестил. А без wait там получается салат с UB и зомби-сыновьями, что при долгом исполнении могут задедлочить прогу. Отака хуйня
Ещё раз, ждать он будет каждый по-отдельности, но работать они будут все (кроме родительского процесса) параллельно, если ты сначала расфоркаешься, а потом будешь ждать.
Нет никакого смысла ждать сразу, если ты хочешь параллельные задачи. Лови SIGCHILD, чтобы узнать, что ребенок умер, и уже тогда делай ему wait.
Это понятно, что ему можно и сигнал обработать, но зачем? Из его описания я понял, что он просто распадается на процессы, что-то делает в них, а потом все их завершает. Тут даже ловить ничего не надо, просто все ожидания повесить в конец программы, и всё.
>>64230
Поясняю: я хотел понять, что делает объект крестов при вызове c_str, чтобы узнать, как долго этот объект хранится в памяти, чтобы понимать, когда зачищать память.
По итогам я понял, что c_str возвращает указатель, привязанный к объекту std::string и зависящий от его существования, т.е. конструкции/деструкции. Его не надо освобождать через free, он сам себя освобождает при delete std::string. Это должно было быть очевидно, но не было.
Уже нашёл лучшее решение первоначальной проблемы разметки памяти под строку через метод strdup. Однако так кодировку можно проебать, ибо 256 значений.
альсо я не с другого языка, я давно забытое вспоминаю.
> кодировку можно проебать, ибо 256 значений
Доброе утро. Вы находитесь в 2020 году, какие нахуй кодировки, если у нас уже много лет UTF-8 повсюду!
>utf-8 внутри объекта, который не предназначен для него
Интуитивно казалось плохой идеей, но обосновать не могу.
> utf-8 внутри объекта, который не предназначен для него
UTF-8 изначально дизайнился так, чтобы быть совместимым с сишными строками.
Ну да, и там и там набор байт, полная совместимость!
>в 2020 году, какие нахуй кодировки
Если вылезти из манямира, то обнаружится туева хуча древнего но вполне актуального прикладного софта, разработка которого корнями уходит аж в 80-е, и относительно которого внезапно есть запрос на поддержку и расширение, но никак не на переписывание единственно-правильным-как-на-дваче-сказали способом.
Ну нет же
https://pastebin.com/SMmhhabn - на сам проверь
Если лень запускать, то вот какой аупут дает программа:
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
And now some other activity, still from 45659, outside of the loop
Random activity from child PID 45660
Yeah, 45659 is still outside of the loop and is going to die NOW
Random activity from child PID 45660
Random activity from child PID 45660
Random activity from child PID 45660
Random activity from child PID 45660
And now some other activity, still from 45660, outside of the loop
Yeah, 45660 is still outside of the loop and is going to die NOW
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
And now some other activity, still from 45661, outside of the loop
Yeah, 45661 is still outside of the loop and is going to die NOW
This child [45659] is dead :(
This child [45660] is dead :(
This child [45661] is dead :(
Dad passes away peacefully...
И где здесь параллельное выполнение процессов? Если бы оно имело место быть, то то, что происходит внутри процессов-детей, не шло бы одно за другим, как видно в аутпуте, а было бы вперемешку, ибо если бы был context switch, то цпу сначала исполнял бы код процесса X, а потом переключался бы на процесс Y и исполнял какой-то кусок кода у него, и так далее. Тут же ясно видно, что создается ребенок, исполняется весь код внутри процесса-ребенка от А до Я, потом следующий ребенок то же самое и так до ребенка N, потом батя получает оповещения о смерти всех N детей один за другим, причем в том порядке, в котором они исполнялись, а потом умирает сам. Где именно здесь параллельное выполнение процессов происходит?
Ну нет же
https://pastebin.com/SMmhhabn - на сам проверь
Если лень запускать, то вот какой аупут дает программа:
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
Random activity from child PID 45659
And now some other activity, still from 45659, outside of the loop
Random activity from child PID 45660
Yeah, 45659 is still outside of the loop and is going to die NOW
Random activity from child PID 45660
Random activity from child PID 45660
Random activity from child PID 45660
Random activity from child PID 45660
And now some other activity, still from 45660, outside of the loop
Yeah, 45660 is still outside of the loop and is going to die NOW
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
Random activity from child PID 45661
And now some other activity, still from 45661, outside of the loop
Yeah, 45661 is still outside of the loop and is going to die NOW
This child [45659] is dead :(
This child [45660] is dead :(
This child [45661] is dead :(
Dad passes away peacefully...
И где здесь параллельное выполнение процессов? Если бы оно имело место быть, то то, что происходит внутри процессов-детей, не шло бы одно за другим, как видно в аутпуте, а было бы вперемешку, ибо если бы был context switch, то цпу сначала исполнял бы код процесса X, а потом переключался бы на процесс Y и исполнял какой-то кусок кода у него, и так далее. Тут же ясно видно, что создается ребенок, исполняется весь код внутри процесса-ребенка от А до Я, потом следующий ребенок то же самое и так до ребенка N, потом батя получает оповещения о смерти всех N детей один за другим, причем в том порядке, в котором они исполнялись, а потом умирает сам. Где именно здесь параллельное выполнение процессов происходит?
ой бля, я обосрался с подливой, я заметил, что тут в некоторых моментах да происходит context switch, хоть и не такой активный, как хотелось бы. А до этого было аутпуты без него, клянусь! Хуета какая-то происходит, ну или я глючу.
Энивей, контекст свич слабоват, процесс ребенка почти полностью выполняется до того, как наступает исполнение следующего. В идеале хотелось бы, чтобы аж посередине цикла был контекст свитч на следущего ребенка, но яхз как это сделать, да и возможно ли
Потому что ос так решила. Ты лучше ос знаешь, когда контекст переключать? Это во-первых. Во-вторых, ты принтфами это не проверишь, потому что они буферизуются.
Это в любом случае сискол, их компилятор изо всех сил будет делать как можно меньше.
Не еби мозг напиши в пару строчек на хаскеле
Если имя-файла заключено в двойные кавычки, то, как правило, файл ищется среди исходных файлов программы; если такового не оказалось или имя-файла заключено в угловые скобки <и >, то поиск осуществляется по определенным в реализации правилам.
>>63477
ну у меня на винде oн всегда сам вoзвращается стрoкoй "Прoграмма была заверешна с кoдoм: ..." и вoт этoт кoд и есть ретурн в oкружение. Тoт ктo прo echo писал видимo линукс имел в виду.
Компилятор слепит твои принтфы в кучу, чтобы не делать много сисколов.
Скажите, а может случиться ситуация, что баги в легаси софте закончатся? Как бы я вижу, что каждый год ловят по пару сотен, а то и тысяч, багов в сишном и плюсовом коде, но баги связанные с памятью (разные переполнения и проблемы с указателями) такое ощущение будто не пропадают, создается иллюзия того, что их бесчисленное множество. Кто шарит и может сказать почему так и почему это не заканчивается? И если когда-нибудь закончится, то когда? 20 лет, а может через 50 лет?
Как писать без багов? Может ли модульное тестирование и контрактное программирование решить проблему?
Интересная теория. Этому есть какое-то подтверждение/математическое объяснение? Или хотя бы статистика? Сам факт бесконечного наличия багов в сотфах косвенно на это указывает?
>у меня сейчас performance-critical личный проект, пердолиться я просто обязан.
Я думал, тебе чисто поиграться, продемонстрировать себе.
Тогда, судя по твои жалобам, ты пытаешься параллелизовать хуёво. У тебя оверхед на отпочковываие процесса сопоставим с полезными вычислениями, в нём проводимыми. Придумывай как нормально раскидывать. Перформанс критикал, май эсс...
Никак. Макаки все равно умудрятся на говнокодить. Для них собственно и созданы такие япы как js/rust итд.
Мой стиль кода на C - писать большую программу, абстрагируя всё что надо с учётом особенностей языка, а когда этот заготовок готов, в нём предсказуемо что-то не работает, и ты как голодный пёс ищешь решения в интернете, а они нихуя не описывают твой случай, поэтому идёшь нахуй.
Это пиздец отстойный подход. Практиковал такое будучи мидлом, потом понял что это всё хуйня, и нужно делать всё bottom-up, иначе всегда есть шанс капитально насосаться.
Как тогда быстрее работать одновременно с N процессами, если не дохуя форков у одного бати? Мультитрединг не катит, ибо тред исполняется в контексте конкретного процесса, а в треде я не смогу вызвать execve. Поэтому без высирания какого-то гипервизора с кастомизированным IO, я не думаю, что есть способ получше работать с большим кол-вом процессов (не тредов!) одновременно. Отака хуйня.
>Опыт.
Хуёпыт. Баги в софте будут всегда, и чем больше кодовая база, тем больше багов, причем зависимость там экспоненциальная.
>Никак. Макаки все равно умудрятся на говнокодить. Для них собственно и созданы такие япы как js/rust итд.
Даже качественный код в больших кодовых базах имеет баги. В говнокоде они очевидные и легкодетектируемые, в хорошем коде они нетривиальные, но они были, есть и будут. Это часть реальности.
>performance-critical
>хуярит execve кучи процессов
Поддерживаю анона выше, тут даже разговора уже нет про перформанс всей этой конструкции.
Софт с багами написан джунами, за которыми не уследили. Или профессионалами, которым не дали времени, чтобы писать нормально. Или это легаси с тех времен, когда всем было похуй. Или это опенсорс, где всем похуй перманентно, и код никто не читает, максимум диффы комита посмотрят. И гораздо реже это новые классы атак, о которых раньше никто не думал.
>>65810
Ты лучше расскажи, какую конкретно задачу ты решаешь.
У тебя есть задача иметь N процессов (повторюсь, именно процессов, не тредов), которые исполняются параллельно и делают что-то. Что бы ты сделал?
>У тебя есть задача иметь N процессов
Что это за задача такая? Конечный результат какой? "N процессов существуют"?
Я пишу фаззер. Я хочу добиться того, чтобы каждый из N процессов хавал свою версию мутированного файла, который им скармливает батёк.
И как тебе в таком случае поможет постоянное переключение контекста? Чтобы помедленнее тестирование было хочешь? Переключение, это дорогая и вынужденная операция, стремиться к ней, довольно странная идея.
А так батей нужно распасться на треды, и ораганизовывать постоянную мельницу съедания и запуска детей, для чего man 3 sigaction придётся изучить.
Как ты из треда (не процесса) запустишь отдельную программу через execve? (в данном случае тестируемую) Это так не работает, тебе process image тестируемой программы перекроет фаззер и все.
форк-экзеком, как и из процесса?
Подробно что именно нужно:
пик 1) Вот есть объявление функции, реализация и вызов, все работает, что логично
пик 2) Есть только объявление функции, но не написана ее реализация, вызвать ее не можем, но без нее тоже все работает, т.е. можно просто объявить
пик 3) Основной вопрос, можно ли как-то чекнуть наличие реализации и только в том случае, если есть, тогда сделать вызов функции
Я не знаю работает ли это, но можно декларировать вызываемую функцию, а затем сравнивать её как переменную с нулём.
тому що функция это просто указатель
Нет, ну если раскомментировать с третьего пика реализацию функции, то проверка что указатель есть сработает, это понятно.
А тут именно в рантайме проверять есть ли реализация, а не на этапе компиляции.
В компиляторах обычно есть поддержка weak-символов. Для гцц можно так: https://pastebin.com/raw/AndYnqYB (попробуй собрать просто так и с -DWITH_FOO).
> можно ли как-то чекнуть наличие реализации
По-хорошему этим должен заниматься твой ./configure, ну или другая часть системы сборки. Или ты можешь вынести такие функции в разделяемую библиотеку и использовать dlopen/dlsym, чтобы искать функции.
>>66094
В студии в свойствах проекта выбери шланговый фронтенд в качестве компилятора (поставь инсталлятором той же студии, если нету). Перед последним аргументом в select поставь &, тебе адрес нужен, а ты в него структуры толкаешь.
В main у меня
example *array = NULL;
Получается мне никак его не передать в функцию?
Т.е. надо писать функцию которая возвращает что-то, чтобы можно было написать
array = myFunction();?
Привет СиТредик, есть тут матеры Си кодеры которые именно работают Си программистами, расскажи что делаете и какой стек надо знать
Я чет нихуя не понял, что ты хочешь, можешь нормально расписать ?
Передача параметров и возврат происходят через копирование в стек. Копировать без надобности большие структуры медленно и плохо, и засирать стек тоже плохо, поэтому по значению передаются только элементарные маленькие типы вроде чисел или отдельных символов. Большие же структуры не передаются, только указатели на них, которые простые числа.
Динамический массив это не массив, а простой указатель на буфер памяти, который ты выделил для своих данных (структур). Если ты выделил память до вызова функции, тогда просто передай указатель в функцию и она с данными через него будет работать.
example ★array = malloc(sizeof(example) ★ ARRAY_SIZE);
myFunction(array);
Если же хочешь чтобы выделение произошло внутри функции, тогда нужно передать указатель на указатель. Функция выделит буфер и присвоит его адрес внешнему указателю через указатель на него.
example ★array = NULL;
myFunction(&array);
void myFunction(example ★★parray)
{
example ★array = malloc(sizeof(example) ★ ARRAY_SIZE);
★parray = array; // вернули указатель наружу
array[0].member1 = ...;
array[0].member2 = ...;
// или так
★parray = malloc(sizeof(example) ★ ARRAY_SIZE);
(★parray)[0].member1 = ...;
(★parray)[0].member2 = ...;
}
>тогда нужно передать указатель на указатель
Не думал что так можно сделать, а NULL передавать бессмыслено. Собственно поэтому вопрос и назрел.
>Если же хочешь чтобы выделение произошло внутри функции, тогда нужно передать указатель на указатель.
До того как я прочитал ответ сделал без передачи через возврат.
Получилось условно:
В майн у меня так и осталось:
example array = NULL;
array = myFunction(99);
Функция приобрела вид:
example myFunction(int count) {
example array_func = NULL;
// Присвоил указателю указатель на выделенный кусок памяти
array_func = (example)malloc(sizeof(example)*count;
// Возвратил получившийся указатель
return(array_func);
}
Выглядит вроде бы корректно.
Сейчас попробую переписать под передачу указателя на указатель, чтобы внутри функции сразу можно было проверять что массив еще не был выделен, а если был очищать его и выделять заново.
... и тут я понял почему звезды
example ★array = NULL;
array = myFunction(99);
example ★myFunction(int count) {
example ★array_func = NULL;
array_func = (example★)malloc(sizeof(example)*count;
return(array_func);
}
>именно в рантайме
Как может получиться, что ты во время компиляции не знаешь, есть у тебя функция или нет?
Спасибо, все получилось.
Корректно будет если я в функции напишу
if (★parray != NULL)
free(★parray);
?
free работает с адресами которые были выделены malloc'ом? Т.е. он пройдет по указателю, увидит адрес и сопоставит с тем что было выделено?
Например, ты пишешь статическую либу. Если пользователь либы реализовал функцию (например, логирование ошибок), ты ее вызываешь. Если нет - предоставляешь реализацию по умолчанию. Хотя обычно делают просто mylib_set_error_log(&user_func).
>free работает с адресами которые были выделены malloc
Да, и только с ними. И еще тебе там не нужен if, потому что free(NULL) делать разрешено.
Так функция и так и так есть, иначе твоя либа или не либа не соберется из за ошибки линковщика.
Вот это и уточнял можно ли как-то определять наличие реализации функции в рантайме или возможности ее переопределения. Ни того ни другого в сишечке нет, чтобы не было привязки к компиляторам.
Поэтому буду через колбеки видимо.
Ты не понимаешь что такое компиляция, скриптомакака.
А можно программу написать, допустим с GUI и консольным выводом в одном исполняемом файле?
Допустим если нет библиотек для gui на компьютере где ее запускают, то можно было ее запустить в консольном режиме.
другой анон
И чё? Указатель на функцию должен быть по здравому смыслу.
либа:
void handler(int user, char name, char value);
int initreghandlers() {
// ...
if (handler = 0x0) return 1;
// ...
}
пользователь:
#include "либа.х"
void handler(int user, char name, char value) {
return;
}
так вейт, по идее либа должна требовать внешний заголовок, в котором дефайним хендлер.
> не соберется из за ошибки линковщика
Я же показал пример: >>66168 Все соберется, все давно придумано до вас.
>>66583
> А можно программу написать, допустим с GUI и консольным выводом в одном исполняемом файле?
В линуксе никто тебе не мешает. А вот в винде GUI/CUI жестко прибито гвоздями в формате исполняемых файлов, и даже если сделать консольное по сути приложение, которое создает окно и прячет консоль, все равно будут вылезать всевозможные косяки, если такое приложение запускать из уже существующей консоли, и еще больше косяков, если запускать его, например, из FAR-а.
Все будет хорошо. Можешь создавать окна из консольного приложения, и можешь создать окно консоли из оконного приложения.
Все отлично работает.
> можешь создать окно консоли из оконного приложения.
Я открыл консоль и написал yoba.exe. Твоя йоба создает окно консоли, НОВОЕ окно. Ты можешь AttachConsole, но так как шелл не блокируется после запуска GUI-приложения, вы с шеллом будете конкурентно срать в консоль, и там наступит полный и совершенно нечитаемый пиздец.
> Можешь создавать окна из консольного приложения
А тут наоборот нельзя вменяемо detach-нуться, чтобы сымитировать поведение GUI-приложения. Т.е., ты запустил Blender.exe из фара, и вне зависимости от того, как ты там настроишь блендер (приложение, у которого subsystem=console), весь фар будет ждать его завершения.
зо тупой вопрос извените
Я всего-то хочу, чтобы -f парсилась после -b, чтобы ради одного конфликта не писать функцию предобработки аргументов последующим звеньям.
В доках нашел ток одно упоминание order, там про другое... Думаю, мб дочернюю структуру argp присоединить с одной из опций, которую хочу позже? Но нигде гарантий не нашел по этому поводу.
asctime(gmtime(time(0x0)))
>argument of type "time_t" is incompatible with parameter of type "const type_t"
asctime(gmtime(time((time_t)0x0)))
>та же ошибка
>>66695
https://en.cppreference.com/w/c
warning: unknown conversion type character 'z' in format [-Wformat=]
printf("%zu\n", s);
Стандарт C11,
gcc version 7.3.0 (x86_64-posix-seh-rev0, Built by MinGW-W64 project)
Это long unsigned. Насколько я понимаю, в стандарте не говорится, какого размера должен быть size_t. По идее, он может не совпадать с long long unsigned, это не так?
your only option is to cast your variables to unsigned long long and use %llu to be maximally portable.
Очевидного говна нет, кода бы немного проблемного
Okey, got it, thank you. But, actually, I don't really understand, why %zu, described in the reference, doesn't work.
https://en.cppreference.com/w/c/io/fprintf
http://cplusplus.com/reference/cstdio/printf/
Лол, это надо в рамку и на стену. Поведение этой программы на самом деле зависит от фазы луны.
>>66777
> С чем связано это предупреждение?
С отсутствующим флагом -std=c11 при компиляции.
>>66857
> бля я идиот короче там 2 звездочки вы поняли
А должна быть одна, это непрерывный массив. Из-за особенностей Си, matrix[SIZE][SIZE] в аргументах функции кастится к указателю, т.е., к unsigned char (∗)[SIZE], т.е., к указателю на массив из SIZE unsigned char-ов. Если внутри функции ты обращаешься к нему по двум индексам, matrix[a], то первый индекс делает прибавляет к адресу matrix sizeof(unsigned char (∗)[SIZE]) ∗ индекс, а второй дереференсит массив. Т.е., массив должен быть непрерывным куском памяти, а не массивом указателей на массив char как у тебя.
Почему-то компилятор (clang 10) векторизует простые операции на 4*u32 в виде массивов, но лепит скалярные __u128_t, оба из одного union-а. gcc вообще пиздец, про него даже не вспоминаю. Подозревал лажу с alignment-ом, но он, как и положено, у неупакованный struct-ов естественный.
Вот код: https://godbolt.org/z/zJ7ZUB
Мне, собсна, зачем: я пишу эмулятор второй плойки, и у её проца куча инструкций типа "параллельно сложи 16 u8 из одного регистра 128" и "сделай xor двух регистров u128". Если компилятор не может из этой нудятины сделать sse2, мне придется дропнуть Си в пользу Крестов, потому что я ебанусь колхозить под них simd библиотеку.
> Пробовал ставить, не помогает.
Должно работать. В гцц поддержка символов форматирования из C99 сделана несколько через жопу, но она уже много версий подряд существует, вряд ли ее сейчас сломали. Ты #include <stdio.h> точно не забыл? Хотя...
> Built by MinGW-W64
вот эти могли. Мне сейчас потестить mingw-w64 не на чем, а вот настоящем mingw все точно было ок.
WSL с убунтой и mingw-w64 поставь и не парься. MinGW-W64 с появлением WSL идёт внахуй.
Да похоже придётся. Самое хуёвое, что штатно оберток над simd и нет нигде: ни в Крестах, ни в Ржавом, ни в Зиге. Ржавый вот уже два года мучает жопу, но не выходит каменный цветок. Повезло ещё, что sse2 и neon почти везде есть, не придется городить cpu dispatch.
Ты даун криворукий и не можешь =/= нельзя сделать. Я постоянно пользуюсь консольной программой создающей графическое окно. Если тыкнуть из проводника создается окно консоли и графическое, если запустить из консоли, занимает консоль пока не выйдет как любая консольная программа, а создается только графическое окно.
> Ты даун криворукий и не можешь
Ты вот прочитать не можешь даже.
> занимает консоль пока не выйдет как любая консольная программа, а создается только графическое окно
Как раз об этом я и говорю. Есть такие требования: иметь опциональную консоль для отладочного вывода. Т.е., чтобы была некая галочка "вкл-выкл консоль" в настройках или соответствующий аргумент командной строки, потому что обычному юзеру консоль нахуй не всралась.
И вот представим, что эта галочка снята, консоль не нужна. Спрятать консоль при запуске с десктопа не проблема, это умеют и делают многие приложения, как, например, тот же Blender. Но нужно еще освободить родительскую консоль, если нас из консоли запустили (FreeConsole()? хуй там!). Вот, например, ты запустил cmd, написал notepad.exe, и у тебя есть нотепад, и его никто не ждет, можешь еще один запустить. Нужно сделать так же. И вот тут ты начинаешь сосать или городить пиздецовые костыли с двумя бинарниками есть еще более костыльный способ - менять подсистему прямо в заголовках собственного exe-шника, но на него возбуждаются антивирусы, поэтому он неприменим на практике.
AllocConsole вкл @ FreeConsole выкл. Если выкл не получается, ищи, кто ещё использует твою консоль. А вообще, ты занимаешься хуйнёй - пиши в log-файл и не шатай анонам мозги.
Накидал пример в виде типа либы для векторов. Понятно, что пользователь сможет задать какой-то несуществующий параметр у вектора типа v[666] и запорот данные. Но как оформить так, чтобы хотя бы уберечь пользователя от ввода вектора разных размерностей?
Пока только вижу, что вектора определять как структуры x,y и x,y,z и там уже внутри он ругнется, когда будет z присваивать.
ну так я и говорю, что понимаю, что новый тип таким методом не создается. Вот и спрашиваю каким методом сделать, чтобы пользователю выдавалось предупреждение, кроме как сделать через структуры. Может есть еще какой-то хитрый способ/общепринятый и гуру.
В сишке классов не завезли, поэтому да - структуры.
-Warray-bounds для предупреждения при выходе за границы
Можно ещё конечно явно передавать длину вектора, как в каком-нибудь memset и проверять длину, но это на любителя.
Кстати, в курсе, что у тебя вектора копируются?
>Можно ещё конечно явно передавать длину вектора, как в каком-нибудь memset и проверять длину, но это на любителя.
ну да, это либо еще передавать длину каждого вектора в функцию, либо завести структуру, которая содержит массив размерностей и размерность
>Кстати, в курсе, что у тебя вектора копируются?
в курсе, это просто пример для вопроса
https://pastebin.com/vcE2tsYC - вектора
https://pastebin.com/DtiEFeG4 - интеграл
Подсобите че к чему, пожалуйста
У меня сейчас проект:
main.c
functions.c //Функции
types.h //Глобальные переменные и описания структур
в main.c
#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
#include <math.h>
#include "functions.c"
в funtions.c
#include "types.h"
По моей логике должно быть так:
После стандартных stdio.h и т.д. должен вставится текст из types.h (т.к. он идет вложенным в functions), затем должен вставится текст из functions.c потом то что написано в main, т.е. должен получится единый длинный файл.
Но судя по всему это работает не так, иначе бы программа скомпилировалась, ведь я ее просто разбил на файлы следуя логике выше.
Компилятор ругается на структуры в майн, будто я их создаю заново и их не было в types.h
>In file included from functions.c:1,
> from main.c:8:
>types.h:17:3: note: previous declaration of ‘GAME_Symbol’ was here
>} GAME_Symbol;
У меня сейчас проект:
main.c
functions.c //Функции
types.h //Глобальные переменные и описания структур
в main.c
#include <stdio.h>
#include <stdbool.h>
#include <malloc.h>
#include <math.h>
#include "functions.c"
в funtions.c
#include "types.h"
По моей логике должно быть так:
После стандартных stdio.h и т.д. должен вставится текст из types.h (т.к. он идет вложенным в functions), затем должен вставится текст из functions.c потом то что написано в main, т.е. должен получится единый длинный файл.
Но судя по всему это работает не так, иначе бы программа скомпилировалась, ведь я ее просто разбил на файлы следуя логике выше.
Компилятор ругается на структуры в майн, будто я их создаю заново и их не было в types.h
>In file included from functions.c:1,
> from main.c:8:
>types.h:17:3: note: previous declaration of ‘GAME_Symbol’ was here
>} GAME_Symbol;
выреди из середины файла кусок и сохрани его в файл filename
потом вместо него в своем мэйне впиши #include "filename"
> Компилятор ругается на структуры в майн, будто я их создаю заново и их не было в types.h
Судя по тому куску, у тебя тайпдеф в main.c. ЗАЧЕМ ты создаешь его заново, если он уже есть в types.h?
Алсо, так никто на файлы не разбивает. Сделай как люди:
functions.c: функции, инклудит functions.h
functions.h: декларации функций из functions.c, инклудит types.h
globals.c: глобальные переменные, инклудит globals.h
globals.h: декларации глобальных переменных с ключевым словом extern, инклудит types.h
types.h: типы (заодно можешь еще почитать, как через тайпдефы incomplete структур скрывать реализацию)
main.c: остальной говнокод, инклудит все .h (но не .c). Собираешь все это говно cc *.c
>ЗАЧЕМ ты создаешь его заново, если он уже есть в types.h?
я не создавал его заново, там в майн было просто:
GAME_Symbol variable = ...;
оно ругалось на все структуры
>Алсо, так никто на файлы не разбивает. Сделай как люди:
Приму к сведению. пока обратно в один файл собрал
да я сам только две минуты как занимаюсь этим. А че ты сказал, куда и что загонять надо?
Сама консоль позволяет запускать в ждущем режиме или прямо сразу продолжать дальше.
А почему ты думаешь, что вычисления неправильные? С чем сравниваешь?
Зачем ты используешь массивы, если можно использовать структуры? Что такое b[0] b[1] и b[2] не понятно, в отличие от b.x, b.y и b.z.
Зачем ты за того антончика отвечаешь, это же явно laba1.
Почему-то червей в учебках всегда учам массивам, вот они их и суют везде в своих домашках. Наверное от ебанутой манеры, что программирование это математика, а в математике часто массивы, структур же в математике нет, вот и шизанутые учителя математики так заливают в тупые бошки школоты.
>вектор матрица
Я и говорю, матиматюхи головного мозга, суют массивы, ведь в математике структур нет.
еще поэтому:
https://cglm.readthedocs.io/en/latest/opengl.html
еще, чтобы писать как на пике 1.
А когда-то лучше как на пике 2.
Вот с юнионом другое дело. Я понимаю, что массив может быть удобен для например автоматического присваивания всех элементов (по индексу удобнее, чем по имени), но это крайние случаи, нормальные имена членов должны быть в первую очередь, а плюшки с индексами только потом.
Так, секунду. А почему это они копируются? Разве запись const Vec3 a в данном случае не аналогично записи const float a[3]? То есть, передается указатель, разве нет?
когда передаешь массив, передается указатель
со структурой или классом создается копия, если параметр явно не передается по ссылке или указателю
Вангую ругается на глобалку.
в main.c создаёшь её инстанс
в main.h декларируешь её и сразу же после пишешь extern глобалка
ну и да, кажется её не мешает статической делать
Макакыч, не рвись, когда-нибудь и ты математику поймешь.
The more you know.
Шаблон порвался чет, думал все выделенное на стаке максимум должно жить внутри одной функции, а по указателям надо передавать все остальное.
func(Vec2 vec), то он копирует структуру или указатель передает?
Union передается по значению. Структуры по значению. Все аргументы в сишке всегда передаются по значению, т.е., копируются.
Единственный нюанс в том, что массивы при использовании в коде автоматически кастятся к указателю на первый элемент (исключение: когда массив является операндом для &, sizeof или _Alignof, он не кастится). Именно это происходит тогда, когда ты пишешь имя массива в аргументах функции: в Си нельзя никак передать массив по значению, потому что на тот момент, когда ты пытаешься это сделать, этот массив уже деградировал до указателя. Зато этот указатель, как и все остальное в Си передается по значению.
Копирует. В Си при передаче аргумента в функцию всегда делается его копия. На самом деле, передача указателя (читай, адреса) это передача копии указателя (копии его значения, то бишь, если в указателе есть адрес 0xdeadbeef, то значение 0xdeadbeef КОПИРУЕТСЯ в функцию). А имея значение указателя (указатель == адрес), вызываемая функция напрямую редактирует данные по указателю, ибо обращается по адресу. Но само цифровое значение указателя при передаче оного в функцию все равно копируется.
Пикрил объясняет эту тему. Ты передаешь указатель в функцию, инкрементишь его значение там (с каждой итерацией он указывает на следующий байт), но при возврате обратно, тот же самый указатель опять указывает на начало строки, в данном случае на букву "Р". Что показывает что РЕАЛЬНО происходит при передаче по указателю (само значение самого УКАЗАТЕЛЯ энивей копируется, прост ов итоге в вызванной функции есть прямой доступ к памяти, но сам адрес энивей копируется). Вывод - в Си копируется абсолютно все (как и, впрочем, в других языках, под капотом оно по одинаковым законам работает)
Спасибо.
Значит получается что, если любой тип данных превышает размер указателя на данной машине, то надо передавать в функцию указатель на него, а если меньше - само значение.
Т.е. например указатель на данной машине занимает 4 байта, тогда char, short, структуру из трех char и т.д. - передаем сам этот тип, а для long long или больших структур - передаем уже указатель на них?
Пиздец, указатель у него копируется.
Указатель - это есть ссылка на ресурс(память), по нему из функции можно найти объект в куче и изменить.
Какие-то хеллоуворлды разбираем, ебемся с семантикой, лучше линукс форкни.
Нет, смотри листинг из годболта выше.
long long ll[3];
Это массив на стаке, неявно он и указатель.
Мы можем получить конкретный элемент через subscript(квадратные скобки) или через *(ll+1), смотри пикрил;
Указатель - это ссылка на объект, а не сам объект. Поэтому при передаче указателя в функцию можно редактировать сам объект.
Чтобы получить указатель на юнион или структуру надо явно взять адрес с помощью &, иначе объект внутри функции будет копией и все изменения не отразятся на изначальном объекте.
Зачем же нужны указатели, кроме как передавать объекты напрямую?
Место на стаке у нас ограниченно, а в куче нет, поэтому используй стак, для локальных операций, которые используют недолговременные объекты, живущие в одной области видимости, а кучу для долгоживущих объектов.
>Указатель - это есть ссылка
Почитай что такое ссылка, она даже записывается не так. И естественно указатель это не ссылка, а обычная числовая переменная без знака, и само собой разумеется она копируется когда передается по значению, как любая переменная.
> Значит получается что, если любой тип данных превышает размер указателя на данной машине, то надо передавать в функцию указатель на него, а если меньше - само значение.
Указатель - это накладные расходы на дереференс и возможно проеб по кэшу, это ограничения оптимизации из-за алиасинга для компилятора.
Я бы вот так исправил твою эвристику: если у тебя размер структуры равен одному или двум sizeof(uintptr_t) - имеет смысл передавать и возвращать по значению. Если это не противоречит сигнатурам других подобных функций в проекте, т.е., чтобы не получилось так, что vec3 у тебя через указатели, а vec2 копируется. Если нет - используй указатели, если нет препятствий к их использованию.
>>68146
> обычная числовая переменная
Привет, шизик, где пропадал? Fat pointers слышал? Far pointers в 16-битном x86 слышал?
Что ты несешь, макака? Указатель - это тип переменной, который хранит адрес. Причем здесь куча вообще? Ты можешь передать массив (массив - указатель на нулевой элемент по сути), который находится на стэке, в другую функцию, чтобы проводить над ним манипуляции, причем здесь блять куча? Про кучу здесь речи вообще не шло.
Ты глаза раззуй и посмотри на код еще раз - когда ты передаешь указатель в функцию, ЗНАЧЕНИЕ указателя (значение указателя == адрес) КОПИРУЕТСЯ в вызываемую функцию (не то, что находится ПО адресу, а числовое значение адреса). Именно поэтому по возврату из функции, где ты этот указатель инкрементил, ты ВНЕЗАПНО обнаружишь, что после возврата он все еще указывает на первый элемент строки, а не на нуль-терминатор, а в предыдущем стэковом фрейме. Вывод - значение указателя КОПИРУЕТСЯ в вызываемую функцию. А из-за того, что вызванная функция имеет значение адреса, она может по этому адресу записывать изменения в данные непосредственно по полученному в аргументе адресу. Если ты не понимаешь сути посыла, то земля тебе джаваскриптом.
Студентоте не париться со всяким спортпрогом или мастхэв циферки рейтинга?
Просто в будущем хочется 100% вкатиться в С, сам читаю всякие нюансы С, системное, сетевое прог.
Сам я нахожу это полезней решать по фасту какую-то поеботину, хотя и полезно для мозга. Не знаю даже...
С другой стороны, специальность у меня не прогерская, у меня спросят, откуда я вообще нахуй вылез без диплома и рейтингов...
Не понимаю.
Решать ничего не прошу, только подсказать, куда копать.
Есть условная игровая камера, у которое есть ветора: позиции в пространстве, куда смотрит и верхнего вектора.
Есть функция, которая передает угол, на который надо повернуть камеру вокруг какой-нибудь оси (в конкретном примере вокруг оси её правого вектора) [картинка 1]
Но камера вращается только не больше чем на 90 градусов в любую сторону от изначального направления. [картинка 2] Серым - мировые оси, красным - начальное положение, зеленым до куда происходит вращение.
Полагаю, что это особенности поворота вектора вокруг оси на заданный градус. Конкретно в этой либе считается через формулу Родрига:
https://en.wikipedia.org/wiki/Rodrigues'_rotation_formula
Написал свою, которая через обычную матрицу поворота вокруг оси:
https://wikimedia.org/api/rest_v1/media/math/render/svg/7dc67eaa6d74f6629767726f854a5ff8bf7e5477
выдает идентичные результаты. Может мне нужно определять в какую полуплоскость и что-то еще проверять..
>Но камера вращается только не больше чем на 90 градусов в любую сторону от изначального направления.
Ты что-то делаешь не так.
Да я понимаю, но не могу понять что)
Сейчас по сути на нажатие кнопочки повешена та функция поворота, в которую передаю маленькое число. Сама камера - просто структура. Крутил и той функцией библиотечной glm_vec3_rotate и для теста накидал по матрице поворота.
Если вот задавать этот угол по нажатию другим, например , как на твоей картинке, то он при единичном нажатии переместится на него, но потом все равно после последовательных нажатий упирается в границы того диапазона в 90 градусов от изначального.
Ладно буду дальше искать свой косяк)
Я не стоял говорить, но у тебя в CameraRotate нужно бы ещё и up повернуть, ты же вращаешь вокруг R, подумал, что так задумано, просто проверь с понятными значениями, что там в D, ошибки в CameraRotate не видно, но перепроверь.
Спасибо тебе добрый человек! Решилось добавлением
glm_vec3_rotate( Camera->up, angle, R );
Вот как всегда забываешь что-то очевидное и в упор сам не видишь..
фысшш >> ascii
Это же работает только для цифр, или я как-то не так пользуюсь?
Гранд мерси, я понял что мне нужно суммировать значение каждого int(str), завтра попробую запилить
щас бы scanf без проверки со строками юзать, мммм
http://sdl.beuc.net/sdl.wiki/Pixel_Access
"Input login" не будет выведено на экран.
Нет разницы. Но константный указатель на массив - это все же int *const arr. А у тебя указатель на массив констант.
Сейчас делается устройство на плис, которая делает расчет и формирует инфу, ну хз, 10 4б слов. Связанную инфу, это всё поля одного свойства.
Как лучше сделать регистры чтения? Первый вариант: (размер регистров пусть 4б) 10# регистров, содержащие нужные поля, а регистр статуса - счетчика, показывающий глубину ФИФО данных, декрментируется только тогда, когда будут прочитаны все 10 полей. Если одно поле прочитать дважды, то на второе чтение будет та же инфа.
Второй вариант: хранить в одном регистре данных всю сериализованную инфу, и получается, счётчик декрментируется только через 10 считываний из этого единственного регистра.
Первый вариант мне кажется наиболее предпочтительным, так как хорошо ложится на любой ДМА, но я опасаюсь, не будет ли коллизий или какого-то такого говна.
Насколько я знаю, константным указателем называется указатель, через который можно осуществлять только чтение, но не запись. Это я имел ввиду.
Подожди. А разве у них sizeof не будет отличаться?
То есть мы можем определить длину массива - sizeof(arr)/sizeof(arr[0]), а с обычным указателем не должно сработать.
Мимо залетный нуб-плюсовик. В C++ это точно два разных способа передачи, хотя я погуглил, пишут, что одно и то же в C.
Не совсем верно.
const int arr <- запрет на запись, но можно указать на другой адрес (в случае массива , например, на следующий элемент)
int const arr <- нет запрета на запись, но сам адрес константен (диаметрально противоположно предыдущему)
const int * const arr <- нельзя ни записывать, ни указывать на другой адрес.
Ты прав. Но в случае с плюсами лучше использовать std::array, нежели сишный массив, ты же все-такт на крестах пишешь, а не на си. А в std::array есть встроенный метод size, который даст тебе размер массива без сишных выкрутасов.
Бля, звездочки стерлись
Не совсем верно.
const int (звездочка) arr <- запрет на запись, но можно указать на другой адрес (в случае массива , например, на следующий элемент)
int (звездочка) const arr <- нет запрета на запись, но сам адрес константен (диаметрально противоположно предыдущему)
const int (звездочка) const arr <- нельзя ни записывать, ни указывать на другой адрес.
Я другой анон, не который вопрошал.
Мне просто стало интересно, так ли сильно отличаются способы передачи.
Так-то я пока не пишу мегаоптимизированный код и пользуюсь векторами, а не std::array.
Я понимаю разницу между const перед звездочкой и после звездочки. Но то, что
>можно указать на другой адрес
неправда. Если ты попытаешься сделать что-то вроде ×(arr+3), ты поймаешь ошибку, потому что arr+3 имеет тип const T×, и не может быть разыменован. Ты, конечно, можешь написать
T× ptr = arr;
но компилятор си за такое, скорее всего, выдаст предупреждение.
Разобрался после какой функции это происходит, почему-то когда SDL переделывает AGBR8888 в RGBA8888 происходит такая петрушка.
Если изначально делать поверхность в одном из форматов, то функция чтения пикселя работает нормально.
Но мне надо все привести к единому RGBA8888 (uint32 0xRR GGBBAA)
Вопрос такой тогда, как мне вручную сделать из пикселя AGBR8888 RGBA8888, т.е. поменять байты местами?
Решение как разобрать переменную побайтово у меня есть:
uint8_t r = (pixel_input) & 0xff;
uint8_t g = (pixel_input>>8) & 0xff;
uint8_t b = (pixel_input>>16) & 0xff;
uint8_t a = (pixel_input>>24) & 0xff;
Как слепить потом это обратно в uint32. Надо к указателю на uint32 прибавлять по uint8 и записывать туда эти байты?
потому что ты хуесос
> мы можем определить длину массива - sizeof(arr)/sizeof(arr[0])
Не можем. Будет sizeof(uintptr_t). Вы заебали, каждые 10 постов одни и те же вопросы: >>67852
>>70208
> пишет ворнинги, почему так
Так исправь их, чего ты жалуешься?
>>70279
> тип const T×, и не может быть разыменован
Охуеть, кто запретит разыменовывать?
> компилятор си за такое, скорее всего, выдаст предупреждение
Можно убирать const явным кастом, это нормально и документировано. Но если исходный объект все же const, ты сам себе буратино. Т.е., int x = 1; const int ∗x_ptr = &x; ∗(int ∗)x_ptr = 2; ок, а вот const int y = 1; const int ∗y_ptr = &y; ∗(int ∗)y_ptr = 2; уже не ок.
@мобератор, можно удалить >>70397 >>70293 >>69499 и это сообщение, это какая-то тупая херня со мной приключилась, заклинило на то что цветной текст не обрезался, оказалось что в SDL2, если цветной текст, он зачем то пустые пикселы подкрашивает, но оставляет прозрачность в 00, а я голову тренировал т.к. у меня вначале была проверка всего пиксела, если он весь (rgba) 0x00000000 то пустой, а когда глиф цветной SDL2 выдает для красного 0xFF000000, короче я теперь по первому байту ориентируюсь.
А зачем тереть-то, если, может быть, кому-то будет полезно узнать.
>> тип const T×, и не может быть разыменован
>Охуеть, кто запретит разыменовывать?
Неправильно выразился, разыменовать, конечно, можно. Я имею ввиду, значение ты не перепишешь. Я отвечал на
>const int× arr <- запрет на запись, но можно указать на другой адрес (в случае массива , например, на следующий элемент)
Я так понял, по мнению >>70109, const перед звездочкой запрещает переписывать только значение, которое записано в указателе.
>> компилятор си за такое, скорее всего, выдаст предупреждение
>Можно убирать const явным кастом, это нормально и документировано. Но если исходный объект все же const, ты сам себе буратино.
Так с этим я согласен. Кстати, можно и не делать явный каст: на си, в отличие от си++, это скомпилируется без ошибок, но с варнингом.
>>70293
>>70586
Во первых ты путаешь две разные библиотеки: SDL и SDL2.
Официальная документация по SDL2 находится тут:
https://wiki.libsdl.org/
Если тебе нужно поменять местами значения rgba у пикселя, то:
считываешь их SDL_GetRGBA() затем меняешь в любом нужном порядке SDL_MapRGBA()
И если уж ты делал по той ссылке, что скинул, то ты точно не забыл заблокировать и разблокировать surface для прямого доступа к пикселям через SDL_LockSurface() и SDL_UnlockSurface()
Короче не путай и тем более не смешивай одновременно обе либы. Используй только SDL2.
Охуеть, не знал
> Когда имеет смысл использовать size_t
Когда переменная имеет отношение к количеству или размеру объектов в памяти. Гарантируется, что нет возможности создать такой массив, чтобы его размер не влез в size_t.
> unsigned
Теоретически может быть меньше size_t, используй для обычных вычислений.
Подхожу к 75% Праты, не подскажите ли где достать пик? Гугл выдает стремоту.
Благодарю.
Я обращаюсь не к массиву, а к конкретному элементу, как указал анон, делаю как в примере из stack overflow, что я делаю не так?
Я тебе не пирожок, крендель. Но сайт годный, запомни его.
Здесь парниша дает ссылку на “C Interfaces and Implementations”:
https://medium.com/@bartobri/the-pointers-to-pointers-idiom-7b15aaafafca
Речь об этом, кто не понял:
https://medium.com/@bartobri/applying-the-linus-tarvolds-good-taste-coding-requirement-99749f37684a
перевод с хабра идет нахуй, потому что хабр идет нахуй с говнорастом
>>71551
Во-первых, читай про приведение типов.
Во-вторых, читай про то, что такое char и какое он имеет представление.
В-третьих, почитай как работают циклы for и как они оформляются.
https://godbolt.org/z/daVcGR
Как же мне стыдно делать такие глупые ошибки, спасибо анон
Тут сегодня анон про материнские и дочерние процессы писал и их параллелизацию. Нашел статью про файловые дескрипторы на хабре, может кому будет интересно.
Это говнокод прыщебати, не мой.
Это лист на массиве. Сипайтон вон везде такие использует.
>Во первых ты путаешь две разные библиотеки: SDL и SDL2.
Доступ к пикселю и записи рабочий.
Сурфейсы лочу и разлочиваю.
Суть в том что я не могу избавится после обрезки от неприятной фигни у прозрачных пикселов (пикрилейтед 1), вместо прозрачности они затемняются. Сначала я думал что из-за порядка ABGR сурфейса который я вписываю (обрезаю) в RGBA сурфейс командой SDL_BlitSurface. Я нашел функцию которой можно превратить в RGBA SDL_ConvertSurfaceFormat из за которой я тригернулся, т.к. вместо FF000000 у меня получились пикселы FF. Из-за этого затупа я написал свою функцию конвертер, которая вернула мне тоже самое FF (и тогда до меня дошло). Потом я заметил что прозрачные пикселы плохо рисуются после функции SDL_BlitSurface, и написал свою функцию которая делает тоже самое. Но блет ничего не поменялось, как были уродские пикселы с прозрачностью так и остались. Пикрл 2, вывод до обрезки и после, вроде одно и то же, а отображаются по разному (как на пикрл 1).
SDL_SetSurfaceBlendMode(surface_output, SDL_BLENDMODE_BLEND); не помогает.
Пс чтобы было понятно. Слева нормальный, справа получающийся после обрезки.
>1671924
почему утекает? там же нет выделения
Разобрался, все таки SDL_BlitSurface портит пикселы, я забыл что использую эту функцию для вставки.
Уверен что в мануале написано как сделать, но я так и не понял как.
Игра с SDL_SetSurfaceBlendMode(surface_output или input, SDL_BLENDMODE_разные); ни к чему не приведа. Да и вообще какого черта это должно было влиять? У меня есть чистая сурфейс с нулями поверх которой я записываю глиф, т.е. там даже при наложении ничего меняться не должно было.
Переписал заново. Изучение продолжается.
>mingw-w64 поставь и не парься. MinGW-W64 с появлением WSL идёт внахуй.
Извини,
Так что поставить и что идет нахуй?
Другой анон.
Если кодишь простые приложения в консоли, можно не ставить MinGW, а поставить debian WSL (или другой дистриб), который доступен в microsoft store.
https://docs.microsoft.com/ru-ru/windows/wsl/install-win10
После установки можно открывать консоль линукса в винде зайдя в папку и нажав SHIFT + правая кнопка мыши. Наряду с "Открыть здесь окно Power Shell" там появится "Отрыть оболочку Linux". Если у тебя debian based, ставишь пакет build-essential.
Для удобства создаешь в папке простой makefile который будет компилить твой main.c
Ставишь vs code + c/с++ intellisens, он автоматом должен инклуды линуксовые подсосать и подсвечивать ошибки.
MinGW-W64 все еще актуален для компилирования под винду.
Мне вот 31 и я вкатываюсь в Си и системное программирование. Вот, что угодно мне будут говорить, но я с большим усердием буду изучать все, что необходимо для вкатывания. Постепенно, день за днем.
Мне просто паста нужна, я не собираюсь в него вкатываться.
Вопрос немного не по теме, но, скорее всего, не все жырные ide одинаково любят C. Я хочу разобраться с одной тяжелой функцией из очень многослойной библиотеки. И вот тут мой подход с блокнотом провалился. Ну вы понимаете, инклюдов десятки, потом еще и еще... Хотеть наиболее продвинутую в плане навигации по проекту (быстрые джампы по файлам, поиск где только можно различных структур и определений) IDE. Желательно, свободную %чтобы я, бля, на её коде тестил%.
W10 + WSL debian
А обязательно через PowerShell?
У меня есть иконка как на пике 1, оттуда запускается, как app.
Xorg это я пытался гуй установить xfce4, он мне выдал на пике 2, ВОУВОУ ПАЛЕГЧЕ, только установил а уже ПЕРДОЛИНГ.
Отвалился пик
>А обязательно через PowerShell?
Там не через повер шел а рядом появляется, пикрл, и он сразу открывает путь этой папки в консоли. Открыл так консоль в папке которой makefile лежит, и сразу набрал make.
>Xorg это я пытался гуй установить xfce4, он мне выдал на пике 2, ВОУВОУ ПАЛЕГЧЕ, только установил а уже ПЕРДОЛИНГ.
Я в том сообщении написал что это в основном для консольных разработок. Можешь запустить эмулятор Xservera - VcXsrv, который ставится отдельно, потом в консольке набрать export DISPLAY=localhost:0.0 и пробовать запускать рабочий стол. Я не пробовал, мне это не нужно, но говорят работает.
Зачем запускать линуксовый декстоп, если можно по человечески поставить дистрибутив? Мне нужны просто инструменты разработчика из линукс, т.к. они более понятны для нубаса, и качаются пакетами, а не по интернету разбросаны.
>Там не через повер шел а рядом появляется, пикрл, и он сразу открывает путь этой папки в консоли. Открыл так консоль в папке которой makefile лежит, и сразу набрал make.
Ах ты ж пирожок! Спасибо!
Их можно несколько запустить найс.
>Зачем запускать линуксовый декстоп, если можно по человечески поставить дистрибутив?
Ну, на той картинке с судоку, была же графика?
Для этого достаточно VcXsrv, окружение качать не надо.
У SDL зависимостей не так много, как у окружения.
Просто запускаю его после компиляции ./sudoku и оно появляется как в виндовом окне.
По советам из интернета вписал export DISPLAY=localhost:0.0 в конец .bashrc в домашней папке (попасть в которую можно cd ~), чтобы постоянно не вводить
> Мне нужны просто инструменты разработчика из линукс, т.к. они более понятны для нубаса
Теперь ясно посему линуксоиды такие тупые. Тольк тупой будет лениться поставить что-то чуть сложнее, но зато потом как сыр в масле кататься с удобствами, нет, он лучше поставит консольку и будет ебаться в неё как инвалид вечно, зато ставить проще, меньше страшных кнопочек и галочек.
>Тольк тупой будет лениться поставить что-то чуть сложнее, но зато потом как сыр в масле кататься с удобствами
Без примеров почему твое видение имеет право на жизнь, ты просто пукнул в воздух.
Какие примеры, довен? Вот нубис втыкает в язык, в нормальном ИДЕ ему подсветятся ошибки, а линуксодебил будет пыриться в портянку высранную в консоль, выискивать номера строк, открывать свой блокнот, выискивать там по номеру эту строчку. Больше делать нечего, такое продуктивное занятие, каждому нубису обязательно пройти, как "не служил - не мужик", то есть "не жрал говно - не программист".
примерно этим отличается академическое обучение от реальной работы
Ты не понимаешь о чем говоришь, поэтому мелишь пургу про консоль, и сидение в блокноте, думая что там какие-то другие IDE.
Человек в си треде не понимает разницы между ос, что ты от него хочешь?
Что мешает линуксмэну поставить тот же VSCode или саблайм, обвешанный плагинами? Имхо, хуйню несешь.
Пиздос, мне уже 40 и я только вкатываюсь.
Ты прав, снёс XFCE, будет только соснолечка с VcXsrv
>про вкат в программирование через большой труд и самообразование
С петухонотредом перепутал?
Завтра ищешь в интернете книжку Керниган, Ричи. Язык C. Похуй если ничего не поймешь. Затем идешь на http://www.utas.edu.au/infosys/info/documentation/C/CStdLib.html и изучаешь стандартную библиотеку от корки до корки. Потом зубришь, именно, сука, вызубриваешь конвенцию по написанию сишного кода - 1TBS, чтобы от зубов отскакивало. Когда напишешь свою первую сортировку Хоара, по пути изучив ассемблер инлайном, скачиваешь и изучаешь любую олдовую среду разработки, рекомендую Turbo C. Как переделаешь сортировку, чтобы была по меньшей мере итеративной, а не рекурсивной, можешь идти дальше - тебя ждет увлекательный мир байтоёбства. Хипсорт, сверхбыстрые асинхронные B-деревья, xor-связные списки. Отсос у хиккующих выблядков / просто неудачников типа рейфага или сисярп/джава-богов, которые работают в тёплом офисе за приличную зарплату не заставит себя ждать и уже через пол года ты будешь так редко мыться, что любая баба будет брезгливо закрывать нос платком при одном упоминании твоей одежды.
не слушайте его, всего этого знать невомзожно. достаточно иметь общие представления и когдав процессе разработки возникают вопросы обращаться к соотвествующей литературе. шизиком стать можно если дрочить это всё.
таким образом можно учиться 10 лет и не написать ни одной программы.
Мне нужно написать на Сишке простенькую систему занятия очереди онлайн. Там есть некоторые требования и лишь одно я не знаю как реализовать. Как сделать чтобы система брала информацию из файла какого-нибудь? Допустим, просмотреть кто еще со мной стоит в очереди и система заполняла строки случайными именами из текстового файла например.
Элементарно же. Открыаешь текстовый файл и пишешь код как его читать, что читать и т.д.
Я не правильно выразился. Смотри, я пишу код в билдере и при запуске он выводится в командной строке. Я хочу чтобы когда я уже встал в очередь, мне предлагали "Хотите посмотреть всю очередь?", я ввожу да или нет, если да то система берет с файла рандомные имена и выводит список с ними и с именем, под которым я встал в очередь, в конце.
Ну. Программа должна после да, обратиться к истоничку где лежат файлы и там по соотвествующим итендификаторам выбивать тебе имена которые в списке. Мне что тебе код написать готовый? Ты элементарный вопрос задаёшь по языку.
Я никак не смог сформулировать свою потребность чтобы загуглить и обратился сюда, код я и сам напишу только подскажите какой или функцию для этого чтобы ее загуглить и изучить.
Ну я же скинул. Функция чтения файла, нет такой функциии "ВЗЯТЬ ИЗ ФАЙЛА И ВЫВЕСТИ ОЧЕРЕДЬ"
Ну то есть оно откроет и выведет то что написано в файле, никакого рандома, я хотел для правоподобности просто чтобы оно брало случайные строки и выводило в случайном порядке и в конце еще и имя введенное до этого. Это не обязательно конечно, но желательно бы.
Та блять я не прошу за меня написать код, всего лишь одну функцию захотел узнать от вас. Спасибо и на том.
Нет. Ничего подобного ты только переключаешь что инпут идёт оттуда а дальше сам решаешь что она будет выводить.
Функции узнаются не от нас, а из документации. И я рад что ты не отрицаешь домашку. Тут тред программирования, "помогать" петухам с домашкой, которым плевать на программирование, нелепо, по теме нужно таких слать подальше.
Та функция что тебе выше скинули, она ничего не выводит. Просто поток переводит на текстовый файл, а далее ты уже пишешь обычный код как если бы вводил с клавы, только ввод идёт не с клавы, а из файла твоего. Я уже не знаю как тебе объяснить кроме как код готовый с комментами написать.
Прата поехавший что-ли?
Почему инициализация через const double, а вызов через int?
Что происходит??
640x480, 0:10
>>73907
>>73910
>сортировка
Есть несколько однонаправленных списков, или как это правильно называется, когда указатель first на первый элемент, и у каждого элемента указатель next на следующий. Все элементы в каждом списке уже отсортированы по int index, который уникален для каждого элемента. Как побыстрее все цепочки объединить в одну с сортировкой по тому же критерию и с исключением повторяющихся элементов? Есть какой-нибудь грязный хак?
Блин, пока думал, как лучше спросить у анона, сам допер.
>- Черновик стандарта ISO/IEC 9899:202x (C2x): http://www.open-std.org/jtc1/sc22/wg14/www/docs/n2385.pdf
620 страниц.
Как только перейдет планку в 700, смысл в изучении "простого и лаконичного" языка испарится, лучше сразу начинать с плюсов.
Пиздец.
Простой и лаконичный пиздец.
Плюсы все еще очень многословные по сравнению со скриптами. Лучше базу делать на чистой сишечке, а нужно больше - скрипт.
Не раз вижу такое:
#define NGINX_VERSION "0.5.4"
#define NGINX_VER "nginx/" NGINX_VERSION
Нахуя такое делают?
И то и другое практически одинаково.
Лол, это ты еще буст плюсовый не трогал и все его глубинные фичи, челики 20 лет на нем прогают и до сих пор знают на 5 из 10
Страусиный труп оценил свои знания сипипи на 7/10, это финиш. В мире есть 2.5 человека, которые могут сказать, что они РЕАЛЬНО знают плюсы (и это главные разрабы плюсовых компиляторов, лол), остальные просто могут писать на нем какой-никакой код.
Да просто опечатка, в одном издании было так, потом поменяли, а в ответах осталось. Должен к этой главе уже сам соображать.
Да я так и думал, просто уже мозг вытекает. Собираюсь добить эту главу.
> лучше сразу начинать с плюсов
Там стандарт короче, да? И легаси нет, и разницы в подходах между C++98/11/14/17/20?
1TBS в этой пасте можно для солидности заменить на SEI CERT C
Никто не ответил, потому что это идиотский вопрос. printf хочет обычную строку, кормить в него L"" - ошибка, об этом тебе мог сказать компилятор, если бы ты потрудился сам эту строку попробовать.
да извини, я перепутал прoстo. этo в либе windows.h в функции messagebox испoльзуется в аргументах
нет. мне ничегo не нужнo я прoстo разбирал winapiшный кoд и не пoнял чтo значит L здесь, теперь, пoнял. спс
MessageBoxW(NULL, szCmdLine, L"Title", 0);
Сереженька)
спасибo, я сам читаю там регулярнo дoкументацию лучше на англ ставить, ибo на русскoм там машинный перевoд
И да, каким образом работает следующий код: (to = from) != '\0' ?
Почему присваивание значения элементу массива возвращает результат?
Ебучий дашчан
ну если автор утверждает чот значит так и есть ибо автор создал этот язык и пиздецть он не будет
Спасибо, стало теперь стало понятно. Автор книги почему-то решил умолчать об этом
Аргументы запихуются в регистры и стек. Попробуй хелловорлд на ассемблере написать по тьюториалу, потратишь час, но все поймешь. Согласно стандарту аргумент type arg[] это эквивалент type *arg, то есть передается указатель. Конечно, строка перезаписывается.
Ты охуенен, анонче!
используй указатели на VLA и будет тебе щастье
double (жmas) = malloc (a ж sizeof(*mas));
mas[x][y] = 14.88;
free(mas);
если приоритет время поиска, то надо делать через хеш-таблицы
если приоритет время вставки, то красно-черное дерево
примерно так понимаю?
И если мне заранее известны все ключи, но важно, чтобы поиск был самым быстрым, то как лучше реализовывать?
upd:
наверное, если ключ в ассоциативном массиве может быть строкой, символы которой состоят только из алфавита в N букв, то самый быстрый поиск - это N-арное дерево, но недостаток, что размер будет больше, вроде так понимаю
Потому, что во-первых, массив - это указатель на первый его элемент, а у указателя нет границ (условно). Во-вторых, в си по стандарту нет требования проверки выхода за границы массива.
а N деревом разве не быстрее? Там же по сути побайтово ключ разбираешь и почти всегда нужен не весь, а тут придется сразу у всего ключа хеш искать
Потому что запись это просто запись по адресу, проверок на границы тут нет. Нужны проверки, сам напиши.
пишутся еще как, раст еще молод, чтобы на него повально переходили
> А что изменилось в C11?
На этот счет - ничего.
> есть ли инструменты, которые будут указывать на ошибку
cc -fsanitize=address hello.c && ./a.out
=================================================================
==79267==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x607000000070 at pc 0x555f0c9161c5 bp 0x7fff99c205b0 sp 0x7fff99c205a0
WRITE of size 8 at 0x607000000070 thread T0
#0 0x555f0c9161c4 in main (/home/anon/a.out+0x11c4)
#1 0x7f23a0979152 in __libc_start_main (/usr/lib/libc.so.6+0x27152)
#2 0x555f0c9160ad in _start (/home/anon/a.out+0x10ad)
Но у санитайзеров есть ограничения, и в некоторых случаях доступ может и не пойматься.
>>76216
> лет через 5-10, когда раст заматереет
Лет через 10 раст давно будет мертв.
>Лет через 10 раст давно будет мертв.
Можешь обосновать? Потому что в общем просматриваются диаметрально противоположные перспективы. Раст: 1) Молниеносно быстр, он в бенчмарках был на равне с плюсами и иногда даже обгонял плюсы. 2) Безопасен. Прощай, произвольное исполнение кода, проблема которая терзала мир инфосека более 30-ти лет. 3) Лаконичнее крестов и гибче, чем Си. Можно разрабатывать лоу-лвл софт гораздо быстрее, чем на си крестах.
С какого перепугу он умрет-то? Перспектива вырисовывается такая, что новый софт будет писаться на расте (уже начал писаться на нем), а С и С++ останется на легаси-продуктах, которые переписать практически нереально (то же ядро Линукса). Но новый софт будет на расте. Почему нет-то? Какие-нибудь железные аргументы есть?
Он все равно не будет быстрее С или в плане потребления ресурсов или в плане портативных систем или новых плат/устройств. Потому что все первым делом пишут компилятор С для своего нового железа.
>на безопасном расте?
Чтобы написать на безопасном раст нужно вначале написать программу на Coq.
>легаси на С/С++
В расте возможно никогда не будет криптолибы на расте, такие дела, и это лишь один пример, будешь свои программы писать через ffi легаси, туда сюда поинтеры кастить, а мог бы сразу написать программу на C и не мучать жопу.
> Можно разрабатывать лоу-лвл софт гораздо быстрее
Проиграл. Сколько часов (и строк) тебе потребуется на анальное ублажение раста, чтобы написать сложную структуру данных, чуть более чем полностью состоящую из укозателей? Ах ты ансейф сделаешь? Тогда
> Прощай, привет произвольное исполнение кода, проблема которая терзала мир инфосека более 30-ти лет.
Итак, мы имеем два стула: либо ты никого не ублажаешь и пишешь на проверенном десятилетиями языке, где все подводные камни давно известны и понятны. Либо ты ублажаешь компилятор в простых случаях (т.е., тратишь больше времени на написание менее читаемого кода там, где на самом деле ошибиться сложно) и ничего не приобретаешь в сложных. При этом у тебя гораздо меньше поддерживаемых платформ, у тебя пляски с бубном для вызова сишного кода (которого охуеть как много в современном мире), у тебя несовместимости между версиями, и впридачу у тебя неадекватное сообщество, которое в основном тратит время на проповеди и на "давайте перепишем это на расте".
>>76326
> Он все равно не будет быстрее С
Будет, но возможный выигрыш не стоит всех этих неудобств.
>Аноны, какой смысл писать новые проекты на С/С++?
Когда у тебя НОВЫЙ проект, тебе нужно как можно быстрее запилить прототип и похуй на его надежность - она должна быть приемлемой. А после этого у тебя проект взлетает, обастает фичами, и уже у тебя внезапно ЛЕГАСИ.
Чтобы что-то взлетело, оно должно быть не безопаснее, а удобнее. У раста есть достоинства типа cargo, но сам язык сильно на любителя, какие-то блядь -> &mut *yoba unwrap(), что это такое вообще и зачем, не программа, а кишки буста какие-то
Растодауны - это сектанты, и поведение у них соответсвующее. Безопасность раста - это миф, просто вдумайся в это. Чтобы написать что-то выходящее за рамки хеллоуворда, код будет состоять на 95% из unsafe. А это смешивает с говном говна любую аргументацию.
Мозилла обосралась, но так и не нашла в себе мужества признаться в этом.
>Некоторые плохие вещи не запрещены в безопасном Rust. Например, разрешено с точки зрения компилятора:
> вызвать deadlock в программе
> совершить утечку произвольно большого объема памяти
> не суметь закрыть хендлы файлов, соединения баз данных или крышки ракетных шахт
ОРУУ СУУКАА
БЕЗОПАСНЫЙ РАСТ
ПИЗДЕЕЦ
>Мы приходим к сделанному раньше утверждению — да, полезность кода на Rust основана на небезопасном коде.
РАСТ ХОРОНИТ С/С++ СПЕШИТЕ ВИДЕТЬ
Кароче ща курю b-tree, думаю запилить свою реализацию (тупо для обучения). И суть в том что b-tree вроде как придуман под работу с большими данными на диске. Типо ебошим размер ноды в дереве размером со страницу которую читаем разово с диска, и таким образом уменьшаем количество чтений с диска. Так вот собственно вопрос, каким хуем можно узнать, какое максимальное количество байт я могу прочитать с файла? именно не вызовом функции, а за одно дрочение головки диска. И где вообще можно почитать как в линухе реализованно чтение с диска. Сам же вызов read читает с буфера в который страницами загружиются данные с диска?
Я даже хз как гуглить это, нифига не гуглится.
>вызвать deadlock в программе
Это нерешаемая проблема тащемта (чекни что такое проблема остановки), но дедлоки не ведут к произвольному исполнению кода, где тебе в очко залетает реверс шелл и полный обоссалити всей системы на выходе.
>совершить утечку произвольно большого объема памяти
Это что еще за бред?
>не суметь закрыть хендлы файлов, соединения баз данных или крышки ракетных шахт
Что не приводит как удаленному исполнению кода.
Я говорил не про то, что этот язык не позволяет написать неуязвимый код, я говорил, что это язык позволяет нивелировать проблемы с памятью (переполнения и дабл фри идут нахуй)
>>76421
Это справедливо для СУПЕРлоулвл софта, где тебе нужно выдрачивать собственную имплементацию связных списков и прочей ебанины, но зачем? Это есть в самом языке, уже реализовано. Куча проектов на 5-10к строк кода без единого ансейфа, ты просто преувеличиваешь.
>>76358
Имея ансейф, ты знаешь где делать аудит кода для поиска возможных дыр, С/С++ - один сплошной UB, особенно С.
>Будет, но возможный выигрыш не стоит всех этих неудобств.
А вот тут не соглашусь, у раста есть рантайм проверки (иначе то же переполнение кучи было бы возможно, ибо там хранятся динамические буферы, размер которых неизвестен во время компиляции). Если весь полностью код на ансейф написать, то он будет быстрый как Си, но быстрее чем Си - вряд ли
>>76326
Ну это сейчас, а потом платформы обрастут компиляторами на раст и все.
Обычный синтаксис, аннотации функций и стрелки из жс.
кароче для линукса нагуглил 4kb
> какое максимальное количество байт я могу прочитать с файла
Незачем оптимизировать 100% случаев. Чаще всего, если ты выберешь относительно небольшой размер страницы (единицы килобайт), физические сектора, которые ее представляют, все равно будут расположены последовательно, потому что драйвер фс стремится по возможности устранить фрагментацию. Алсо, ты можешь спросить размер сектора/кластера в томе у ОС. Или можешь дать юзеру выбор - так, например, делает SQLite.
> за одно дрочение головки диска
Во-первых, у нас кроме жестких дисков с головками есть SSD, а там все очень непросто, и разброс размеров физических страниц достаточно большой. Во-вторых, у жестких дисков наружу тоже торчит абстракция, и реальный размер сектора узнать не всегда возможно.
>>76544
> Это нерешаемая проблема тащемта
Нерешаемая в целом, решаемая в частных случаях, как и все остальное в айти. Алсо, в сишке очень просто притащить локфри-структуры, уменьшив количество возможных блокировок.
> Имея ансейф, ты знаешь где делать аудит кода для поиска возможных дыр
Никто не анализирует исключительно ошибки с памятью. Ищут различные проблемы, в том числе обычные логические ошибки. Поэтому по-любому придется читать весь код.
> А вот тут не соглашусь
Сишные компиляторы сильно упираются в alias analysis при попытке векторизовать/реордерить вычисления/откладывать записи и т. д. Существующих strict aliasing и restrict всегда будет недостаточно (даже если будут атрибуты из C2x, ты заебешься ими все обмазывать), и вот тут у раста все шансы.
>реверс Шелл
Ты либо из 2010, либо вообще ни малейшего представления не имеешь о чем говоришь, дальше не читал.
Спс за ответ, но я все равно нихуя не понял.
> Во-первых, у нас кроме жестких дисков с головками есть SSD, а там все очень непросто, и разброс размеров физических страниц достаточно большой. Во-вторых, у жестких дисков наружу тоже торчит абстракция, и реальный размер сектора узнать не всегда возможно.
так как же тогда поступать, тупо взять какое-либо значение близкое к реальности и не париться? Опросил я ОС сказала 4кб размер сектора.
Бля, кто знает, где можно почитать от том как ОС работает с диском и как вытаскивает/засовывает данные через системные вызовы? Я так понимаю что возможно последовательность расположение узлов дерева в файле будет тоже играть роль но производительность? или я уже поехал?
ты еще скажи что это невозможно, лол, ору
CVE-2019-11932 приятного аппетита, почитай про этот CVE, охуеешь. И это еще просто громкий случай, таких дыр еще миллион в самом разном коде, будь то ядра ос, будь то какая-то либа, будь то просто прога на с/с++. Да что уж там говорить, у меня у самого на счету 2 CVE, один из которых zero click remote code execution. Поучи меня еще тут, щенок
> Бля, кто знает, где можно почитать от том как ОС работает с диском
Почитай ридми Виктории, там черным по белому написано, что с диском работать можно только в XP, 7 уже ограничивает доступ, а 10 тем более, они даже программу ухудшают из за ограничений десятки, прямо так в изменениях написано "мы ограничили функционал программы из за проблем в windows 10".
Так а как шелл то в итоге выполнить? Стек и куча неисполняемы. Искать адреса необходимых функций в подгруженных, так это не тоже самое, что произвольный шелл запустить, абсолютные адреса могут меняться, повезет - не повезет.
Я не тот кому ты отвечал, так мимокрокодил.
Была мысль давно сериализацию в Си для себя замутить, но потом ее оставил, как раз из-за того, что произвольный шелл неисполняем при стандартных настройках ОС. Вот интересно стало
Никто уже не впендюривает в тупую шеллкод в стэк и не прыгает на него через скомпрометированный адрес возврата или указатель на рандомную функцию. Есть замечательная вещь под названием возвратно-ориентированное программирование, почитай на досуге, если интересно, это обходит data execution prevention (то, что ты назвал неисполняемым стэком и кучей). А его современная модификация полностью обходит Control Flow Integrity - самую современную технику антиэксплуатации. Насчет адресов - information leak. Рандомизация адресного пространства - сильная вещь, но полностью разбивается об примитив произвольного чтения. Если ты можешь спиздить со стэка/кучи/откуда-либо угодно адрес - ты можешь посчитать любой другой адрес в сегменте откуда был спизжен адрес (при рандомизации адресного пространства рандомится базовый адрес, а не все по отдельности, а если бинарь не был скомпилен как position independent executable, то образ бинаря в памяти, то бишь секция кода и данных, не подвержена рандомизации адресного пространства). Причем не всегда нужно прибегать только к технике возвратно-ориентированного программирования, можно через примитив произвольной записи подготовить данные на стэке для вызова функции, которая добавляет флаг исполняемости конкретной странице памяти (в Линуксе этот сисколл называется mprotect, хз как в винде) и тогда вуаля - стэк/куча вновь исполняемы, прямом как в начале нулевых. Различных техник и их комбинаций - бесчисленное множество.
И это только верхушка айсберга, к тому же я не могу в одном посте написать о всех нюансах, это целая наука.
Я спрашивал, подразумевая линуху. Не думал что тут в шиндоузе сидит кто-то. Шиндоуз еще жив?
А, точно, си же не мейнстрим, вот и притягивает хипсторов повыебываться нитакими какфсе. Социошлюхи ради социоблядства лезут в якобы программирование. Тупой мерзкий цирк уродов.
я не понял что ты спизданул. как по мне, хуйню какую-то
Вот это тебя порвало на ровном месте.
>>77202
линуксо-мразь, ты? недавно один такой хуесос красноглазый пришёл и выёбывался "А ПАЩИМУ У ВАС ПРАЕКТ НА ВИНДОВС ЭТО ЧТО НЕОБХОДИМАЯ ОСОБЕННОСТЬ ПАЩИМУ" потому что долбаёб ебаный ВСЕ АБСОЛЮТНО ВСЕ БУХГАЛТЕРА И ПРОЧИЕ ТЁТИ СРАКИ СИДЯТ НА WINDOWS И ПОКУПАЮТ ПРОГРАММЫ НАПИСАННЫЕ ПОД ОКНА ДЕГЕНЕРАТ ТУПОЙ БЛЯДЬ НАХУЙ
СОВСЕМ ПИНГИВИНЫ ЕБАНУТЫЕ МРАЗИ. ВНЕЗАПНО ВАЙТИ ЭТО НЕ ТОЛЬКО ЕБУЧЕЕ АДМИНИСТРИРОВАНИЕ НА ОБОССАНОМ КОНСОЛЬНОМ ПОРАШНОМ ПИНГИВИНЕ ДЛЯ НИТАКИХ КАК ФСЕ ДЕГЕНЕРАТОВ ЕБУЧИЙ ОБОССАНЫХ ЛИНУКСОИД МРАЗЬ СДОХНИ ГНИДА ЕБАНАЯ
>си же не мейнстрим
>в топ 1-3 TIOBE на протяжении десятилетий
>охуилярд софта написано и все еще пишется на си
>ядра всех известных ОСей, драйвера, прошивки, новомодный IOT, рилтайм, системный софт
>lingua franca языков программирования, альфа и омега всего мира компьютерных технологий
>не мейнстрим
Красиво стелишь, фраерок :-)
тише, петушок, иди лучше телеметрию в своем тормознутом говношиндоусе выруби. Заодно проверься на наличие криптомайнера, не помешает.
> кроссплатформу
Потратить десяток тысяч человекочасов, чтобы полтора аутиста-линупшодебила смогло воспользоваться продуктом? Нет, спасибо
На линуксе софта вообще нет, даже майнеры никто не хочет под это говно писать, потому что у 80% линуксоидов слабые компы.
Вот бомбануло-то чела
А макосеры?
>>77500
Кстати стоит отметить, что про баб-срак я образно выразился, ибо софт для бухгатлерии поделил уже давно 1С. А вот конкретно я пишу софт для всевозможных лабораторий химических. Инженерный грубоговоря, наша компания числится в списке партнёров лукойла и мы продаём софт за дохуищные деньги непосредственно им под их заказ на их компы.
И нас никто и никогда не просил писать под линукс в требованиях всегда стояла возможность запуска win7\10 Линуксы ваши нахуй никому не нужны, программы должны быть ещё с гуи к тому же ты бы ещё приебался нахуй гуи чому сосноль не прикрутили. Потому что люди которые ими пользуются не знают про линукс и про консоль, это инженера которым нужно в 2 клика вбить значения и нажать кнпоку рассчитать всё. И ПРОСТО БЛЯДЬ ВЫСШАЯ СТЕПЕНЬ ДЕГЕНЕРАТИВИЗМА КРАСНОГЛАЗОГО ПИСАТЬ СОФТИНУ КОТОРАЯ ИСПОЛЬЗУЕТ GUI ОТ ОКОН И БУДЕТ РАБОТАТЬ ТОЛЬКО ПОД ОКНАМИ НА ЛИНУКСЕ, СУКА ТЫ ДЕГЕНЕРАТИВНАЯ.
Это всё здорово, но из твоих слов очевидно, почему в требованиях к вашей фирме линукса нет. Под линукс просто в менее боеготовой фирме заказывают.
СУКА ТУПАЯ скоро всех переведут на русский линукс и надо будет весь софт переписывать, и тут на сцену выйдем МЫ.
Он уже выше начал за обе стороны играть, зачем ты его кормишь?
Очень часто нечто может находиться в конечном наборе состояний. Если нужно прыгнуть в N участков, то удобно switch делать. switch красиво с enum
Это безопасно, чтобы ты не присвоил чертовщину и не попал в default: блок зря.
Ещё это отличный способ объявить константы в хедере, без необходимости обсуждать это с линкером.
define надо избегать, если можно сделать через enum.
В том виде, в котором они есть в языке - нахуй не нужны, максимально кривая фича. Если бы идентификаторы скрывались в отдельном неймспейсе своего enum, и если бы можно было задавать типы для самого enum, тогда в них был бы смысл.
>>77874
> Это безопасно, чтобы ты не присвоил чертовщину и не попал в default: блок зря
Это если ты константу присвоишь. А если значение в компайл-тайме не известно, ты понадеешься на компилятор, и он тебе не поможет, но ты об этом не узнаешь.
> define надо избегать
Вот да, еще одна проблема enum в том, что ты токой
enum myenum { SOME_FLAG = 0x40000000, SOME_OTHER_FLAG = 0x80000000 }, и компилятор токой WARNING: ISO C RESTRICTS ENUMERATOR VALUES TO RANGE OF 'INT' (2147483648 IS TOO LARGE)!!!111 Поэтому максимум, что можно пихать в енумы - вот эти самые имена состояний конечных автоматов или там теги для юнионов. Как только в твоем enum появляется явный = с хотя бы одним фиксированным значением, стоит задуматься о дефайне, потому что дальше будет только хуже.
окей, работа работой. ну заставляют тебя хуй лизать и жопу сосать, но чтобы пользоваться этой парашей в свободное время, я этого не понимаю.
>недавно один такой хуесос красноглазый пришёл и выёбывался "А ПАЩИМУ У ВАС ПРАЕКТ НА ВИНДОВС ЭТО ЧТО НЕОБХОДИМАЯ ОСОБЕННОСТЬ ПАЩИМУ"
Потому что говноеды тупые, с профессионализмом как у хлебушка. Кроссплатформа это не только линукс, это в принципе гарантия отсутствия любых проблем с твоим кодом в будущем.
А на поделия подобных говноедов я за 20 лет насмотрелся, еще начиная с досбоксов и патчинга софта в 6 студии, потому что в более новой не заведется. То есть говноед заранее расписывается, что он пишет распильный софт со временем жизни 1-2 года. А многие люди свой код для вечности пишут.
> Кроссплатформа это не только линукс, это в принципе гарантия отсутствия любых проблем
Это миф. Не существует кроссплатформенного кода сложнее хелловорлда. Тебе нужно работать с файлами, рисовать окошки, звук играть, интернеты асинхронно дергать. И на каждой платформе все это реализуется по-разному и содержит кучу нюансов. Поэтому написать под конкретную платформу вменяемую прослойку-абстракцию иногда сложнее, чем основную логику программы, которой эта прослойка нужна.
Так все уже написано. Поэтому все и сводится к заплывшим жиром кузьмичам с синдором NIH, нежеланием разбираться и "я 20 лет под винапи пишу, что мне переучиваться что ли". Хули, лукойл, место пригретое, левых бабок много и каждый заинтересован попилить с них кусок.
> Так все уже написано
Это только так кажется. А потом ты такой опа, и хочешь узнать, не являются ли два файла хардлинками одних и тех же данных, или расположены ли они на одном физическом томе, или является ли filename валидным именем файла, или >>76540
... и, короче, либо у тебя тонны зависимостей, у каждой из которых собственная проблема, либо ты пишешь решение под задачу сам.
> все и сводится к заплывшим жиром кузьмичам с синдором NIH
Со временем у тебя накапливается количество случаев, когда ты взял вот эту крутую либу, которая решает твою проблему, и ты ее используешь, и все заебись. Но сильно позже в ней обнаруживается фатальный недостаток, который удается обойти только дикими костылями. При этом авторы либы не считают это проблемой. И с опытом ты начинаешь гораздо более скептически относиться к модным крутым либам.
>Так все уже написано.
Вот из-за таких педерастов как ты сейчас все пишется на высокоуровневой залупе типа электрона,все жрет по полтора-два гигабайта на пустом месте и лагает
Конечно разные. Раньше педерасты на высокоуровневой залупе типа С писали, вместо нормального ассемблера.
хуйня,предпочитаю писать на перфокартах для максимального перфоманса
Ну так берешь SDL2 + imgui и пишешь нормальный кроссплатформенный софт для инженегров, чтобы они ввели значения в поля и ткнули кнопочку "рассчитать". Логику ты пишешь сам всех этих лукойлов, что тебе заказывают, кроссплатформенное у тебя только создание и рендер окна, устройства ввода-вывода, сеть, gui
> SDL2 + imgui
Лол, использование ненативного гуи, да еще требующего аппаратного ускорения для двух кнопочек (привет, remote desktop) - это прямо классический детектор эталонного студентософта.
Что за бред ты написал, потрудись объяснить человеческим языком.
Насколько эта реализация очереди хуёва?
научись писать чистый и читабельный код для начала, там дрисня какая-то несусветная
Спросите профессионального программиста, как устроена система Windows, и вы услышите горестный вздох. В лучшем случае вам еще сообщат, что лучше бы вам этого не знать.
И в самом деле, Windows содержит огромное количество никому не нужных функций; припомните, к примеру, многосотенные списки недокументированных функций да функций-заглушек, не то еще не реализованных, не то забытых вовсе. В частности, сама многооконная среда используется довольно редко, большую часть времени пользователь работает с окном, развернутым на весь экран. Концепция же функции окна, как и вся система событийного управления, неизменно приводит меня в праведную ярость из-за разбазариваемых впустую ресурсов.
Впрочем, пользователю все это неизвестно - от него структура Windows старательно скрывается. Такое укрытие структуры операционной системы осмысленно в компьютерах Macintosh, рассчитанных на самого неподготовленного пользователя-мне хватило десяти минут работы на Маке, чтобы разобраться в работе большинства установленных приложений - в системе же Windows, имеющей обыкновение периодически рушиться под собственным весом, пользователь имеет право знать, что у него лежит в каком каталоге.
Осмелюсь напомнить тем, кто забыл, как выглядит DOS, что для его функционирования достаточно наличия всего трех файлов общим объемом чуть более ста килобайт (я лично после работы с мастдайкой - Windows 95 - стал путать килобайты с мегабайтами), а все необходимые драйвера устанавливаются очевидным образом. Только в DOS чувствуешь себя полновластным хозяином собственного компьютера.
Часто достоинством Windows считается унифицированный графический интерфейс, например, общие шрифты. Но стоило ли огород городить, если оные шрифты с тем же успехом могут использоваться и в DOS, достаточно распространить средства их отображения в виде драйвера для DOS. Что же касается пресловутого OLE, гипотетическая его реализация под DOS наверняка работала бы быстрее и стабильнее; тем же, кто обвинит меня в притягивании за уши, отвечу, что OLE именно за уши Мелкософтом и притянут - так не лучше ли было притянуть его к DOS?
Спросите профессионального программиста, как устроена система Windows, и вы услышите горестный вздох. В лучшем случае вам еще сообщат, что лучше бы вам этого не знать.
И в самом деле, Windows содержит огромное количество никому не нужных функций; припомните, к примеру, многосотенные списки недокументированных функций да функций-заглушек, не то еще не реализованных, не то забытых вовсе. В частности, сама многооконная среда используется довольно редко, большую часть времени пользователь работает с окном, развернутым на весь экран. Концепция же функции окна, как и вся система событийного управления, неизменно приводит меня в праведную ярость из-за разбазариваемых впустую ресурсов.
Впрочем, пользователю все это неизвестно - от него структура Windows старательно скрывается. Такое укрытие структуры операционной системы осмысленно в компьютерах Macintosh, рассчитанных на самого неподготовленного пользователя-мне хватило десяти минут работы на Маке, чтобы разобраться в работе большинства установленных приложений - в системе же Windows, имеющей обыкновение периодически рушиться под собственным весом, пользователь имеет право знать, что у него лежит в каком каталоге.
Осмелюсь напомнить тем, кто забыл, как выглядит DOS, что для его функционирования достаточно наличия всего трех файлов общим объемом чуть более ста килобайт (я лично после работы с мастдайкой - Windows 95 - стал путать килобайты с мегабайтами), а все необходимые драйвера устанавливаются очевидным образом. Только в DOS чувствуешь себя полновластным хозяином собственного компьютера.
Часто достоинством Windows считается унифицированный графический интерфейс, например, общие шрифты. Но стоило ли огород городить, если оные шрифты с тем же успехом могут использоваться и в DOS, достаточно распространить средства их отображения в виде драйвера для DOS. Что же касается пресловутого OLE, гипотетическая его реализация под DOS наверняка работала бы быстрее и стабильнее; тем же, кто обвинит меня в притягивании за уши, отвечу, что OLE именно за уши Мелкософтом и притянут - так не лучше ли было притянуть его к DOS?
> А почему ты там не прочитал, как очередь сделать?
Не дочитал ещё до этого. Хотел сам как-то изъебнуться
Никогда не лагало. Лагали только игры с графоном если не купить видеокарту. Сейчас же лагает всё, даже игры без графона при наличии видеокарты (они теперь в процессоры встроены). А звук лагает вообще безальтернативно, ведь микрософт выпилила звуковые карты, оставив полусофтверные затычки. Раньше кстати быди подобные затычки, только диалап-модемы, полусофтверная параша. В результате пошла мода на юэсби-бирюльки с лампочками, вообще высеры с хрипом пердежом и отсутствием звука, ведь официальной поддержки нет, даже в DOS было намного лучше.
>Никогда не лагало
Ты зумер или алкаш, который остатки мозга пропил? Можно ведь просто взять ретрокомп и понаслаждаться этой нелагающей работой и, конечно же, стабильностью всего этого говнософта
Я тоже вкатывальщик, решил как анон реализовать очередь. Поревьювьте кто плз https://pastebin.com/Zxm465qx.
Еще такой вопрос, я выделяю память для новой ноды при добавлении елемента. Я так понимаю каждое новое выделение памяти - это минус производительность. Есть ли какой паттерн, чтобы все время не выделять память, а один раз выделить допустим на 100 елементов, и потом динамически перевыделять если количество елементов больше 100 стало?
{
GAME_Cell ★★cell;
GAME_Cell ★★cell_xy;
}
Анончик, есть структура сетки, внутри которой есть указатель на ячейки. Первый это для доступа к ячейкам как одномерный массив [N], второе как к двумерному массиву по [n][n]. Основным является [n][n], в [N] хранятся указатели на ячейки из [n][n]. Это дело инициализируется кодом пикрл 1.
Почему у меня не работает код на пикрл 2, для перестановки двух ячеек между собой?
Допустим при перестановке [0][0] = 1 и [0][8] = 9 на выходе получаю:
[0][0] = 9, [0] = 9 (верно)
[0][8] = 1, [8] = 9 (при доступе в одномерном массиве старое значение).
Т.е. в одномерном массиве у меня ссылается на старое значение, но я же вроде бы в функции копирую значение, т.е. адрес должен остаться старым, а значение должно измениться.
Что я делают не так?
Стракты сломаны, один тайпдеф, другой не тайпдеф, название тайпдефа совпадает с названием структуры (компилятору-то понятно, что где, а человеку?).
Нейминг конвеншн какой-то рандомный, что за внезапная "__prev" с двумя подчёркиваниями, когда ни одной другой такого вида переменной нет? К чему это?
Подход с void × element довольно странный. Если ты организовываешь очеред, то, предположительно, ты данные откуда-то получаешь, и после прохождения очереди, они куда-то уходят. А тебе придётся ещё административную логику их хранения где-то отдельно городить.
Никакого хендлинга ошибок.
Зачем маллокать кью на куче, когда она состоит из одного указателя и одного инта? (и бай дизайн, в такой структуре максимум может ещё пара указателей появится) На стеке её оставляй.
Ну и по мелочи, указатели без констов, хотя в функции ты ничего не меняешь.
И у тебя очередь LIFO получилась, это точно то, чего ты хотел? (поэтому комментарии нужны). Обычно лифо стеком называют, а очередью FIFO.
>Есть ли какой паттерн, чтобы все время не выделять память, а один раз выделить допустим на 100 елементов, и потом динамически перевыделять если количество елементов больше 100 стало?
Есть такой паттерн, реаоизовывай.
лол, точно, я же ебаный стэк сделал. Надо проспаться.
Ты же два раза маллокаешь место для геймгрида, это два разных участка памяти. В ините() ты копируешь двумерный грид в плоский, но когда ты их местами меняешь, ты же больше не в ините(). У тебя где-то должны быть юнионы вместо страктов, но без ide чужой код читать не хочется, а качать и открывать его хочется ещё меньше.
Всё равно лучше переделай архитектуру, у тебя сейчас очень странно всё.
Импотент делает игру - The Code
Забавно как психика у людишек работает. По факту сделано всё возможное, чтобы не делать игру, но поциэнт считает наоборот, что делает игру.
Спасибо за подробный ответ. В качестве техник обхода что-то похожее и пердставлял. Про возвратно-ориентированное почитаю - интересно.
>Еще такой вопрос, я выделяю память для новой ноды при добавлении елемента.
Можно арену ебануть.
мимо-питоноблядь
> Это миф. Не существует кроссплатформенного кода сложнее хелловорлда. Тебе нужно работать с файлами, рисовать окошки, звук играть, интернеты асинхронно дергать. И на каждой платформе все это реализуется по-разному и содержит кучу нюансов.
Не на каждой. Это винда стоит боком и не следует стандартам POSIX.
Просто берёшь и пишешь, потом прогоняешь валгриндом.
> Это винда стоит боком
Этот реверт лилипута. Соит только винда, в всё остальное жмется по углам как крысы ненужные, а то и вредные.
о бля, спс, анончек, это то что я хотел
Любитель придираться, да.
make - говно, но ничего лучше нету.
Это же стандарт, для любителей компиляторы писать. Простые смертные читают k&r и он всё ещё актуален.
> Это что еще за бред?
Память разметил, но не освободил. Хроническая проблема мозилки с 2000х годов, буквально багрепорт такой давности открыт, но в расте не разрешили.
Хромоговно сейчас может работать аптайм неделю. Лиса не может, лиса обсирается.
> Не на каждой. Это винда стоит боком
Конечно. У меня от тебя epoll/kqueue. inb4 select в 2020
На всех суперкомпьютерах мира стоит Linux. На роутерах и большинстве серверов тоже. Что сказать-то хотел?
Хотел сказать, что есть больше двух операционных систем, а серверами мир не ограничивается.
весь Интернет держится на Линуксе, пчел. Тебе этого уже должно быть достаточно, чтобы прекратить бессмысленный и смешной спор.
А весь десктоп на виндоусе
И? GTK на них не работает? Может, они posix не совместимы и приходится переписывать? Нет, не приходится.
Ммм, таки множество функций и не работает, есть make-флаги, есть linux compatibility layer в ядре netbsd, есть ядро линукса и линус со своим "люди важнее стандартов", что порождает некоторые линукс-специфичные фичи, на которые люди опираются. Короче говоря, пакеты под бзди нередко требуют портинга. Причём проссать что не заводится не всегда возможно, т.к. в бздях make расцветает невиданными бутонами, если конечно вам что-то захотелось собрать самому
Попробуй, кстати, под линухом скомпилировать какой-нибудь kde 20 летней давности, потом раскажи как пройдет.
>библиотеки на линуксе не библиотеки и не считаются
Вот вот, на линуксах все проблемы решаются по принципу неуловимого джо - если есть проблемаа, значит она неправильнаяч и не считается, а значит проблемы нет. В результате проблем не существует, идеальная система шизомирка дебилов
> >библиотеки на линуксе не библиотеки и не считаются
Ты не понял. У новых версий может быть несовместимость со старыми.
Это не отмазка, а факт. По ссылке шиза, признаю. И СПО – это не один Linux.
Ну да, поэтому старые версии не нужны и не существуют, а значит и проблем с ними связанных нет.
>У новых версий может быть несовместимость со старыми
>может быть
Всегда есть. Потому что новое это прогресс, а старое - говно и нинужно. Причем процесс обновления идет беспрерывно и что было прогрессом сегодня, завтра уже нинужное и не существует. И это замечательно, а вот в "дерьмовой винде" совместимость зоть 30 лет назад, вот же куча говна, ха ха.
Есть книга Петцольда "Programming Windows 95". Все примеры оттуда запустятся на десятке, и практически весь контент актуально и сейчас.
Раскажите мне про "код для вечность" в линухах.
Независимо от треда фанбои линукса это студенты и админы низкого уровня (которые остаются в душе студентами до пенсии).
Красноглазик, принеси-ка книжку по разработке гуи под линух 90х годов и попробуй запустить что-то оттуда на современной убунте.
>Если линуксовый драйвер уже несколько лет не поддерживает какой-либо функционал в железе, то мало того, что функционал нинужен, так ещё и производитель железа – урод и может довести торвальдса до слёз и публичной истерики (см. случай с nVidia).
Другой анон на проводе.
Вот нынешним студентам смешно это читать и могут даже не понять. А у меня реально подгорело. 8 лет назад пытался на ноут compaq установить пинус. Естественно, нихуя нормально не работало и я полез на форумы. БЛЯДЬ, мне отвечали слово в слово как выше БЛЯДЬ!
Красноглазик, тебе сказали что делать:
>книжку по разработке гуи под линух 90х годов и попробуй запустить что-то оттуда на современной убунте.
Покажи свой "код для вечности"
Не знаю, на что ты рассчитываешь, учитывая, что *никсы всё никак с говна из 80х для своей графики слезть не могут
https://en.wikipedia.org/wiki/X_Window_System#Release_history
(а прослойка совместимости с ним скорее всего теперь вообще не уйдёт никогда)
Но, почему-то мне кажется, что спорить с человеком, который для "победы" готов свой же аргумент на 180° развернуть, довольно бессмысленно. Мои аргументы ты будешь крутить, как фингерспиннер.
Карманов - птушник-кинфоцыган, а с какого-то времени и пропагандон, нашел кого приносить приличным людям.
>Есть книга Петцольда "Programming Windows 95". Все примеры оттуда запустятся на десятке, и практически весь контент актуально и сейчас.
И как же автор этого добился? А он выкинул нахуй visual studio и сказал людям ебаться с командной строкой и мейкфайлами. Потому что Петцольд умный, а ты нет.
Изначально-то речь была о том, что нет никакой причины в 2020 не писать кроссплатформенно и так делают только непрофессиональные васяны. Кроссплатформенно - это значит не закладываться ни на какую платформу. Ну то есть, не надо ни использовать winapi, ни xwindows, не надо в гуе писать важную для программы логику, и так далее. Понятно, что васянам это сложно - ну на то они и васяны. Тупые-с.
Учусь по Прате.
Использую devc++, но не тот который на bloodshed а новый, с
https://sourceforge.net/projects/orwelldevcpp/
Почему? Потому что проскакивал в тредах, начал и понравилось, т.к. он довольно прост - что хорошо для новичка.
Зашел как-то посмотреть сорцы, внезапно оказалось что они на делфи.
Еще оказалось, что фронтенд программы - это формочки! Для тебя это наверное естественно, а для меня одной магической штукой меньше.
Я решил в свой "дипломный проект" перегнать это в си. Соответсвенно, GTK.
Меня очень удивил main.pas:
https://sourceforge.net/p/orwelldevcpp/code/ci/master/tree/Source/main.pas#l11
6656 lines (5916 with data)
+6k строк в одном файле! Чому так??
Почему не вынести часть в отдельные файлы, а потом подключить через extern хз как это в делфи?
Хотя, может gtk тоже высрет 9000 строк в один файл, не знаю.
Я кончел.
Просто хотел поделится.
> Чому так?
Ну так в делфи принято: form.dfm для самой формы, и form.pas соответствующий класс к ней. Кое-что вынести, конечно, можно, но для этого телодвижения нужны, а делфи так удобно позволяет создавать методы полутора кликами. Вот и получилось.
Мне 31, хотя какая разница, васян? Это за тобой, васян, кроме возраста, нихуя нет. Так же как у карманова, гоблина, рандомного специалиста по ремонту ваз 2106 и прочих одноклеточных. Такие не умеют спорить с аргументами, вот и выдумывают себе противника. И это удобно, потому что молодые и неопытные бывают где угодно, поэтому спорить нужно, естественно, выдумывая именно их.
Обиженку обосрали на русском форуме - как будто на других русских форумах того времени такого не было. Ну да, линукс виноват в токсичной атмосфере на русских форумах. То ли дело форумы по винде - там все в деловых костюмах занимаются делом.
>А он выкинул нахуй visual studio
Красноглазик, ты свои картинки-то читал? Он использует MSVS 4, и мейкфайлы. В то время это было обычной практикой.
>Изначально-то речь была о том, что нет никакой причины в 2020 не писать кроссплатформенно
Есть причина, например чтобы использовать нативные хорошо документированые АПИ, а не убогие "кросплатформенные" библиотеки. Чтобы использовать DX12 вместо уебанского Vulkan, и т.п. Если ты пишешь под десктоп, ничего кроме Windows тебе поддержить не нужно.
>так делают только непрофессиональные васяны.
Тебе-то то откуда знать, васян?
>не надо в гуе писать важную для программы логику
Охуеть откровение.
> спорить с аргументами
> васян
> васян
> васян
> ни одного аргумента, только чужие мысли про кроссплатформенность, зачем-то смешанные в одну кучу с разделением логики и интерфейса
> а ваши аргументы не аргументы
>Почему не вынести часть в отдельные файлы, а потом подключить через extern хз как это в делфи?
Нахуя? Это имеет смысл при командной разработке.
Когда ты один, хуячишь себе и хуячишь, при случае ctrl-f работает.
Ах да, еще обязательно нужно упомянуть линукс на суперкомпьютерах, как будто ты вот только сегодня свой говнокод там запускал.
> Он использует MSVS 4, и мейкфайлы
А я напомню, что Visual Studio сама мейкфайлы использовала. Ее проекты с расширением .mak (4 студия) и позднее .dsp (как минимум 6 студия) - это точно такие же мейкфайлы, с расширенным синтаксисом для nmake.
Содомит
Не знаю, у меня просто травма с qbasic, читать длиннющие простыни с go-to. Да, я альтфак.
Именно Кнута необязательно, но что-нибудь по алгоритмам все равно почитай, Седжевика того же.
Я запускал на суперкомпьютере свой говнокод только раз, это был код на паскале через зеленый монохромный терминал с кнопками почти как на пишущей машинке. И кстати, линукса там не было, даже командной строки классической не было, а была графическая табличка-меню в аски-графике, и ты из этого меню выбирал вводя номер пункта ниже, называлось кажется "командник", мы даже сами делали свои взамен стандартного. Вот, наже в дедовскмх шкафах с жесткими дисками как грампластинки, и то были графические интерфейсы.
Советую книгу "Грокаем алгоритмы". Там на уровне детей, с картинками, объяснено минимально нужное.
Потом уже можно какого-нибудь Кормана навернуть
Смотри на ютубе канал OLD ROBOT — это я.
exercism.io
codewars.com
hackerrank.com
https://app.codility.com/programmers/lessons/1-iterations/
Типа
struct huyna h = {
{"sghdfgh","dfghdfgh"},
{"dfghdnb","dfjghkldjgh"}
};
Мне нужно чтобы освобождать переназначенную маллоком память было удобно, тому що если вызывать free() на статическую память, выходит UB. Решение - маллочить всё и освобождать всё, но как маллочить хз.
Хотя маллочить что есть в статике это изначально говнокод. Программа запускается и что делает? Делает strdup'ы строк, которые есть в статике.
Хмм.
Ну выделяешь malloc(sizeof(struct huyna) * count), в чем вопрос-то? Строки можешь хранить в таблице (string pool) - выделить большой кусок, (опционально) искать там строку, а если ее нет - дописывать в конец. Когда кусок кончится - выделить новый, и т. д.
Вы видите копию треда, сохраненную 31 августа 2020 года.
Скачать тред: только с превью, с превью и прикрепленными файлами.
Второй вариант может долго скачиваться. Файлы будут только в живых или недавно утонувших тредах. Подробнее
Если вам полезен архив М.Двача, пожертвуйте на оплату сервера.