Тред, посвященный прародителю всех С-подобных языков и по совместительству единственному идеальному и всесторонне годному средству программирования как на системном, так и на прикладном уровне.
- Очевидный GCC. - clang: оче годно, батя рекомендует. - Intel C++ Compiler: оптимизации, тысячи их. - Visual Studio Community Edition: внезапно этим стало можно пользоваться, особенно с тулсетом clang/C2. Поддержка C11 на уровне "есть все, что тебе понадобится в реальном проекте плюс кривая библиотека". Анализатор кода в комплекте. - Pelles C (шиндоуз онли): поучиться, вкатиться в C11 (стандарт полностью реализован, имеются в том числе threads.h и прочие stdatomic.h), но количество багов в оптимизаторе и редкие апдейты напрочь отбивают желание собирать этим что-то сколько-нибудь серьезное. - TCC: очень маленький компилятор с багами и поддержкой C99. С ключом -run умеет компилировать код в память и запускать его, что позволяет писать скрипты прямо на сишечке.
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)
- https://godbolt.org/ - Compiler Explorer позволяет посмотреть выхлоп компиляторов для введенного куска кода (больше полусотни разных версий компиляторов). - http://cdecl.org/ - С Gibberish ↔ English помогает читать сложные сишные декларации.
Си говно говна, хуже чем си вряд ли что-то есть. С++ уже почти нормальный язык, за некоторыми исключениями оставшимися от наследия си. Rust нормальный язык, вполне годный для замены первого говна.
Единственный вопрос треда - Нахуя вы продолжаете жрать говно?
>>2165553 Си лучший из лучших, прошло 40 лет, но лучше си врядли что-то появится. С++ уже почти нормальный язык, за некоторыми исключениеми добавлеными поверх си Rust самый конченый язык, создан СЖВ скамом, чтобы выебать программиста в жопу своим борроу чекером и конченым синтаксисом, чтобы пополнить ряды пидорасов.
Единственный вопрос треда - почему мы тут все такие пиздатые?
>>2165786 Глянь проекты трансух и фурриебов, обнаружишь, что почти все они железнячники и пишут на си. Про трансух на cppcon все знают. На расте же пишут белые цисгендерные мужчины. Даже на rust survey были диаграммы, в которых 90% растоманов не относили себя к меньшинствам.
>>2165792 > Глянь проекты трансух и фурриебов, обнаружишь, что почти все они железнячники и пишут на си так раньше было, да пидоры писали на С, как и все, ничего плохого в этом не вижу. Но вскоре времена поменялись, пидоры фемки и вские другие залупские меньшинства начали вещать свои извращеные идеи громче всех, эмулируя своим ором массовую поддержку (на самом деле их как было 1% так и осталось). Это сказалось на многие вещи, БЛМ, поблажки неграм и пидорам почти во всех сферах, также и в программистской среде это тоже случилось (пример - замены master slave). Из-за общего тренда (а не из-за своих личностных качеств) эти никчемные фемки и пидоры дорвались до власти, и смогли навязать что надо написать свой раст. Т. к. идея его создания высосана из пальца, а истинная причина - (они даже это во всех статьях так и пишут) убить детище белых гетеросексуальных мужчин (с с++), то новый язык получился как и собственно идея его создания - КУСКОМ ГОВНА. > Даже на rust survey были диаграммы, в которых 90% растоманов не относили себя к меньшинствам. ага, спасибо что посчитал по головам тупых ебланов. Будет новый тренд ебать своих мамок - увидишь теже лица
>>2165553 >Си говно говна, хуже чем си вряд ли что-то есть. Си это такой высокоуровневый ассемблер. Например, когда я пишу на Си, я знаю какой машинный код сгенерит компилятор. Си++ это (Си + синтаксический сахар). Почти всегда я тоже знаю что сгенерирует компилятор. Но только почти.
>>2165841 Во-первых, это слова Линуса Торвальдса. Во-вторых, давай будем честны друг с другом, ты ничего такого низкоуровневого не пишешь, чтобы знать какой там ассемблер будет сгенерирован.
Смысл высокоуровневых языков, в том, чтобы во-первых, разработка конечного продукта происходила быстрее, и во-вторых, чтобы в этом конечном продукте было меньше багов. Говносишка как ты и сказал это реально высокоуровневый ассемблер, где среднестатистическая макака наделает сотни багов с доступом к памяти, мемори ликов и если дело происходит в многопоточной среде кучу data race'ов. Я конечно понимаю что среднестатистическая макака считает себя ассом и думает что она не наделает ошибок, но как показывает статистика это далеко не так.
К тому же нормальный человек видит задачу и решает ее высокоуровневым методом, а говнари на си, будут 90% времени ублажать компилятор и процессор. А на выходе получат только баганное говно которое будет постоянно падать и жрать память из-за мемориликов.
Ребята подскажите что делать, если при компиляции такая ошибка возникает?
libmingw32.a(main.o):(.text.startup+0xa0): undefined reference to `WinMain@16'
В интернете пишут, что типа делается не в консольном приложении и нет функции main. Проект не мой, но нужно скомпилировать. Если тупо засунуть в рандомный файл эту функцию - то, конечно, компилируется и получается экзешник но программа там не работает.
>>2165905 Обычно линкер отлично сам детектит, какая функция есть (main или WinMain), подсовывает соответствующий стартап, и все работает. Без исходников сложно понять, что ты делаешь не так, и что именно ты сломал. Попробуй -mconsole сказать.
>>2165865 > нормальный человек видит задачу и решает ее высокоуровневым методом Он на 100% не знает, что там внутри высокоуровневого метода, документация почти никогда четко не описывает контракт, и мы получаем что? Правильно, вот это твое > сотни багов с доступом к памяти, мемори ликов и если дело происходит в многопоточной среде кучу data race'ов Особенно последнее. И как он будет это решать? Отладить все эти мегатонны говна невозможно, поэтому он бездумно натыкает мьютексов, но ничего не изменится, все станет только хуже.
Плохой код на крестах писать гораздо проще, чем на сишке. А если заодно вспомнить, что кресты - это не один, а четыре разных языка (C с классамии и три основных стандарта), становится ясно, что лучше на крестах не писать вообще.
Есть некая функция (обработчик прерываний), которая в цикле обходит некий массив. Функция обобщённая и использоваться будет на нескольких устройствах с несколько разным набором элементов в этом массиве. В данным момент там просто static массив в том же файле, но хочется вынести оттуда.
Как лучше это сделать: 1. extern my_data_array и инициализировать этот массив в файле, включённом только в нужном таргете 2. void register_data_array(_type d, size_t s) { my_data_array = d; my_data_size = s;} и вызвать её во время старта, передав туда нужные данные (выбранные по какому-то принципу 3. Пойти вопреки гайдлайнам и вынести объявление и инициализацию этого static массива в другой .c файл (где уже и будет ветвление в зависимости от таргета) и просто сделать "#include my_data_array.c"?
>>2166051 Минусы первых двух вариантов в том, что размер массива уже не известен на стадии компиляции и становится проблематичным создание второго массива того же размера, разве что опять же делать его extern или передавать в register_data_array. Уж не знаю, как этого можно избежать.
>>2165986 При чем тут С++. Я согласен, что на С++ нахуевертить по незнанию можно так же как и на Си а то еще хуже. Я говорю о высокоуровневых языках типа хаскеля, где проблемы решаются высокими абстракциями, без всяких там мутексов и прочей низкоуровневой хуйни. Где априори не может быть дата рейсов, сегфолтов и мемориликов. Но даже если брать с++, то во-первых, мы не берем в расчет всяких джунов, а берем в расчет среднего мидла, которы уже умеет программировать на своем языке и знает где вставить мутекс и т.д. и если взять такого же среднего разработчика на си и дать им одну и ту же задачу, шанс того что на си будет больше багов намного больше и время которое он затратить реализуя какую-то сложную вещь на си написывая все с нуля начиная от примитивных дата стракчерс будет вообще не сопоставимо со временем которое потратит С++-Чэд, просто заинклюдя в свой проект буст и реша проблему в пару сотен строк.
>>2165553 >Си говно говна, хуже чем си вряд ли что-то есть. >С++ уже почти нормальный язык, за некоторыми исключениями оставшимися от наследия си. >Rust нормальный язык, вполне годный для замены первого говна. На новой архитектуре/платформе компилятор и окружение раста не собирается без компилятора си и плюсов, вот и думай теперь.
>>2166056 > размер массива уже не известен на стадии компиляции Есть еще четыре возможных решения: - вместо register сделать функцию-геттер, которой будет видно определение, и она сможет возвращать и указатель, и массив (плюсы - не нужно заботиться о том, не забыли ли вызвать register при инициализации); - создавать переменную с размером с помощью макроса и магии (вполне нлом, если стайлгайд осуждает макросы); - положить массив в отдельную секцию и считать размер секции (типичное решение в embedded, когда и компилятор тебе известен, и линкер ты контролируешь) - ну и возможно стоит подумать о том, нужен ли тебе вообще размер - возможно, нуль-терминатор в конце тоже подойдет. Я бы сделал register, раз уже известно, что код будет переиспользоваться. Тем более на STM32 писать подобное в традиции.
>>2166172 >И нахуя ты это высрал? >При чем тут си? При том, что где будет раст, там всегда будет Си и плюсы. А вот в обратную сторону это не работает. Тогда встает вопрос, нахрена он нужен и как он может заменить си, если сам без него не собирается?
>>2165865 >Во-первых, это слова Линуса Торвальдса. Может быть. Но это, пожалуй, единственное в чём я разднлю его взгляды.
>Во-вторых, давай будем честны друг с другом, ты ничего такого низкоуровневого не пишешь, чтобы знать какой там ассемблер будет сгенерирован. Если ты давно тут тусуешься, то наверно видишь вот такие скриншоты. 75% из них мои. С учётом того, что обычно я не использую плавающую запятую, а только целочисленную арифметику (данный скриншот исключение и проект не мой) то вполне хорошо представляю что сгенирует компилятор.
>А на выходе получат только баганное говно которое будет постоянно падать и жрать память из-за мемориликов. Если ты больше 20 лет пишешь на Си, то твои программы не будут падать и течь, потому что это всё пройденный этап.
>>2166698 >Эти FPU инструкциии Лол, а че sse не завезли?
>Если ты давно тут тусуешься, Нет, я тут особо не тусуюсь и не знаю кто ты и что ты делаешь, я иногда забегаю засрать макак от нефиг делать.
Но твои маняпуляции с ассемблером лишены смысла, ибо где нужна пиздецовая оптимизация берут интринсики и пишут на них, тут хоть на с++ пиши хоть на расте хоть на хуясте, ассемблер будет одинаковый. В остально смотреть что там высрал компилятор - бесполезное занятие. Я в свое время тоже и на си писал и на ассемблере и интринсики юзал в хеви оптимизированных функциях. Но я пришел к тому что си - это говно которое несет вред и по-хорошему его надо запретить вообще.
>Если ты больше 20 лет пишешь на Си, то твои программы не будут падать и течь, потому что это всё пройденный этап. Если ты больше 20 лет пишешь на си, то с тобой явно что-то не так, при чем сильно.
>>2166723 >Если ты больше 20 лет пишешь на си, то с тобой явно что-то не так, при чем сильно. А кто тебе сказал что я пишу ТОЛЬКО на Си? Зарплату мне платят за C#. На сях и плюсах я пишу для души.
>>2166736 >C# >На сях и плюсах я пишу для души. Ясно, с этого и надо было начинать.
>>2166763 х87 сопроцессор уже лет как хуй знает сколько не используется даже для одинарных вычислений. Попробуй дизасемблируй любую арифметическую функцию и увидишь там simd инструкции для одиночных скаляров.
>>2166797 Ты еблан. Даже объяснять тебе что-то лень. Иди учи матчасть. При чем здесь новая архитектура и си? Твой компилятор ( любого языка ) должен преобразовывать высокоуровневый код в машинные инструкции этой архитектуры и взаимодействовать с операционной системой через syscalls, в стандартных люнуксах за это отвечает glibc или аналоги, но никто не мешает тебе сделать тоже самое на другом языке. При чем здесь си еще раз?
>>2165466 (OP) >Brian Kernighan, Dennis Ritchie "The C Programming Language": Хотел бы совета насчёт перевода данной книги, какой самый лучший из всех ? В ориге не осилю, ибо слабо знаю английский.
Здравствуйте, я немного запутался в указателях, вот, к примеру у меня есть указатель ptr, для которого я выделяю 5 ячеек памяти: int ptr = calloc(5, sizeof(int)), можно и с malloc(5 sizeof (int)). Правильно ли я понял, что если создать другой указатель pptr и присвоить ему ptr: int pptr = ptr, то я смогу делать все с указателем ptr через pptr, в том числе и free(pptr)=>очищу так же и ptr, т.к. все это ссылается на один адрес в памяти, это справедливо будет?
>>2167712 Эти числа нельзя представить точно в виде суммы положительных и отрицательных двойки. Округляй или ограничивай количество цифр после запятой более вменяемым числом. Алсо, lf тебе не нужно, ты печатаешь дабл, это просто f, а long double это уже Lf.
>>2167454 На ptr твои манипуляции не повлияют, они влияют на объект, на который ссылается ptr. Просто после free объект удалится, но ptr не "очистится", оба указателя будут продолжать одинаково указывать на невалидный объект. Захочешь очистить - пиши NULL в каждый по отдельности.
>>2168023 Нахуй нужны индексы в массиве? Я что, не могу без них обойтись чтоли? Указатели на обычных машинах - это индексы в массиве байтов под названием память.
>>2168732 А в чем тут собственно проблема? Да, неизвестно какие байты ты получишь, на бульбуляторе с не IEEE-шным флоатом и/или little endian. Правда при условии что размер и выравнивание у типов одинаковое. мимо из крестотреда
>>2169025 > А в чем тут собственно проблема? strict aliasing. Стандарт не гарантирует возможность доступа по несовместимому указателю, а компиляторы этим пользуются. В таком простом коде, конечно, не сломается, но в каком-то другом - обязательно.
>>2168901 >>2169103 Тогда нужен каст не в uint32_t, а хотя бы в uintptr_t (а то сломается на 64 битах) или поменять формат на %p. И с этим после ассемблера тоже сложно смириться. Ты знаешь, что там лежит, а компилятор Си выделывается и не хочет.
>>2169332 > И с этим после ассемблера тоже сложно смириться. Ой, да ладно. Я сначала Бейсик выучил, потом ассемблер, затем ассемблер другой архитектуры, затем паскаль, затем Си. На Си сложно было переходить, но ассемблер тут не при чём.
>>2169332 > И с этим после ассемблера тоже сложно смириться. Ты знаешь, что там лежит, а компилятор Си выделывается и не хочет. Вот поэтому я и не осилил си. Слишком много букв а толку ноль. Один хуй никакой совместимости в реальных проектах между архитектурами не существует, все равно нужно править и переписывать код при любой смене окружения. Что именно даёт си, что все так любят его,мне не ясно. А вот отнимает он очень порядошно.
>>2170364 >Один хуй никакой совместимости в реальных проектах между архитектурами не существует Сморя чего пишешь, если GUI, то не существует. в остальном хватает #ifdef
Ну и как бы выносишь интерфейсные части в отдельную сущность, а логика платформонезависима. Для многопоточности пишешь свой враппер. И проблема совместимости исчезает.
По сути есть лишь две платформы Windows и Posix-like.
Наконец, если интерфейсная часть твоего проекта получилась больше, чем логическая, то это повод задуматься - нахуй нужен такой такой проект. С вероятностью близкой к 100% это очередная "свистоперделка".
>>2170543 > По сути есть лишь две платформы "Две" платформы - только для хелловорлдов (даже для хелловорлдов уже две).
На самом деле есть x86/ARM (там уже куча вариантов, у кого какие интринсики есть, какие требования к выравниванию и прочая подобная хуйня). Кроме того, даже процессорных архитектур у тебя все равно сильно больше: как минимум, рано или поздно придется MIPS, RISC-V вон наступает. Плюс у всего этого есть разные разрядности. И ОС. И версии ОС. И разные версии либ.
> в остальном хватает #ifdef Ты забыл рассказать, сколько строк кода в тех ifdef. В этом вся суть. От того, что ты сложил разные реализации в один файл, они не перестали быть разными, и сишка переносимее не стала.
> логика платформонезависима Да, пока ты пишешь тормозное говно на жс.
>>2171080 cmake -DCMAKE_YOBA_ABC=1 -DCMAKE_HELL_KNOWS_WHAT=zzz -G "ХуйПоймиЧто". Ошибка! CMAKE_YOBA_ABC теперь надо писать как CMAKE_YOBA_DEF, и похуй, что во всех гайдах утверждается обратное. CMAKE_HELL_KNOWS_WHAT не поддерживается престарелой версией CMake. CMAKE_C_STANDARD=17, я такого не знаю, идите нахуй. И вообще компилятор не найден, зато вот у вас sh.exe есть, поэтому я собирать не буду.
Нет ни одной вменяемой системы сборки. Это как с лефтпадами в жс. Тебе их рекомендуют для не того, чтобы решать проблемы, а для того, чтобы у тех, кто рекомендует, была работа.
>>2171063 >(даже для хелловорлдов уже две Пиздёжь. printf есть везде. За редчайшим исключением, типа прошивой для какой-то экзотической ёбы. Да то не факт, что его там нет, скорее всего будет через JTAG писать в терминал.
Цишники блять, а ну быстро пояснили Питоногосподину почему чар залупа = "А" это H через %с в принтф, че это за хуйня? инбифор: Я знаю что А выводится через одинарные кавычки нормально, я спрашиваю какого хуя Н через двойные выводится
>>2171699 А лол, ну так на вопрос то ответь, какого хуя с двойными кавычками такие фокусы нужны, схуя они не эквивалентны одинарным для ситуации одного чара.
>>2171702 Потому что 2 кавычки это строка, а когда ты бля выводишь через %c ты выводишь СИМВОЛ, %c - char/charachter/символ Вот тебе пример с %c и двойными кавычками и %s.
>>2171704 Это я понимаю, я не понимаю почему Н выводится без фокусов с указателями. Что вообще такое Н? Ну ок я дебс в чар строку запихнул и решил ее через %с вывести лулзов ради. Почему оно не кидает ошибку или первый символ строки, а кидает какой-то Н. В чем смысл?
>>2171707 > Ну ок я дебс в чар строку запихнул Это как? В твоём примере zalupa это указатель на строку. Когда ты перед ним пишешь звёздочку, это разименовывание указателя называется, на выходе будет первый символ.
А у тебя 'A' кириллическая или латинская? Вероятно кириллическая, потому что другой ошибки быть там не может.
>>2165466 (OP) Сап, нюфажеский вопрос. Есть алгебраическая функция, непрерывная, ф1. Есть функция, которая считает производную от этой функции, назовем ее ф2. Но вот есть функция, которой нужна и функция ф1 и функция взятия производной ф2, пусть будет ф3, например разложение в ряд или что-то еще. Как добавить ф2 в ф3 в качестве аргумента чтобы ничего не сломалось?
>>2173151 Выделять на стеке можно (не забывая, что стек не резиновый), передавать мелкие тоже можно (например, чтобы наколхозить именованные аргументы), крупные/разнородные лучше передавать указателем.
>>2172676 Ты не в том треде интересуешься. Тут нужен код. А вообще гугли "указатель на функцию". Его можно передавать как аргумент функции. И чтобы не ебацца понапрасну, объяви его как typedef, инвче хуй голову сломает - получится нечитаемая конструкция, которую даже автор кода не поймёт. А через typedef указателя на функцию получится вполне читаемое.
>>2175027 Нет. Можешь сделать typedef структуре из трех байтов, но арифметики к ней конечно не будет. Нативно 24 бита будет только там, где 24-битные инты. Старые dsp например.
Какие есть нетривиальные но хорошие способы изучения Си? Курсы может какие нибудь, бут кемпы там? Книги мне тяжко осиливать, а вот, например, туториалы хорошо заходят
Тред, прошу о помощи. Учусь в шараге, учат сям (точнее, гибриду сей и с++, так как препу не хочется учить нас сишному вводу-выводу). Задание: решить методом хорд уравнение arctg(x)-0.5=0. #include <iostream> #include <math.h> #include <stdlib.h> using namespace std; double f(double x) { double y = atan(x) - 0.5; return y; } double h(double a, double b, double d, double e) { double c, dprog, eprog; int i = 0; while ((abs(f(b)-f(a))>e)&&(abs(b-a)>d)) { c = a + fabs(f(a) / (f(b) - f(a))) (b - a); if (f(a)f(c)<0) a = c; else b = c; i++; eprog = abs(f(b) - f(a)); dprog = abs(b - a); } cout << dprog << endl << flush; cout << eprog << endl << flush; cout << i << endl << flush; return(c); } int main() { double a1, b1, c1, d1, e1; cin>>a1; cin>>b1; cin>>d1; cin>>e1; if (f(b1) * f(a1) >= 0) { cout << "ERROR"; return 1; } else { c1 = h(a1, b1, d1, e1); cout << c1 << endl << flush; return 0; }; } При a1=-1, b1=1, d1=0.1, e1=0.1 работает нормально, но если задать иные значения - виснет. Если компилировать пошагово непонятно, что с ней - тоже виснет, как только переходит на вычисления. Это у меня глюки на ноуте или у программы проблемы? Прошу о помощи. Да, я знаю, что хуй и быдлокодер, но я только учусь
>>2179705 > учат сям (точнее, гибриду сей и с++, так как препу не хочется учить нас сишному вводу-выводу). вся суть снгшного образования плюнь в лицо этому преподу от меня
>>2180562 тогда посмотри пож-та на 24-ю строчку. там вроде тоже адреса сравнивают? Эта строчка должна определить какая строка больше и укоротить её до размера destination.
>>2180567 Такие махинации возможны в пределах одного массива. Точно не помню, но стандартом гарантировано, элементы массива распололжены в памяти последовательно, поэтому адрес n-1 элемента меньше/больше это зависит от системы адреса n-го элемента на определённое число байт.
>>2180566 там же memmove написано. если адрес dst больше src, значения пишутся типа от конца, если нет, то к концу. len может быть любым неотрицательным, но есть риск записать больше и что-нибудь испортить. Алсо, не ясно, что происходит при перекрытии адресов в ходе записи.
>>2165466 (OP) Я из C# треда, но лучше спрошу тут, т.к. вопрос для байтолюбителей. Есть два массива: int[] src и int[] dst (вместо int можете подставить что вы там любите, типа uint32_t). Как мне скопировать произвольное количество битов, заданных позицией первого бита start_bit_index_in_src, количеством битов bit_count и позицией в которую начинаем копировать в получателе: start_bit_index_in_dst. При этом, все прочие биты в массиве-получателе, должны остаться неизменными. Я начал писать код, и он оказывается очень сложным. Приходится писать отдельную логику для первого элемента массива, для последнего и для внутренних. Приходится писать отдельную логику для случаев, когда смещение первого бита в первом элементе в src больше, чем в dst, для случае - когда меньше, и когда равно. Вроде бы задача тривиальная казалась на первый взгляд, но что-то я закопался.
Есть одно очевидное решение в лоб, сделать метод для чтения и присваивания отдельного бита, типа bool get_bit(int[] arr, int offset) и void set_bit(int[] arr, int offset, bool value). Оно простое в реализации, но вероятно будет намного медленнее, чем если копировать целыми кусками int.
>>2183331 В составе стандартной библиотеки armcc есть _membitcpybb() и сопутствующие, но это не является частью стандарта. Погугли, может кто-то запилил кастомную реализацию.
>>2183331 > Приходится писать отдельную логику Страшно-то как. Так же как и в реализациях memcpy: если хочешь быстрое блочное копирование, ты пишешь отдельную логику (читай: побитовое копирование или ебля со сдвигами и переменными-аккумуляторами) для невыровненной части данных в начале и в конце. Другого не дано.
>>2185736 Да, но в идеале надо ещё делить на размер элемента массива, если размер каждого элемента массива больше минимально адресуемой единицы памяти.
Ребяты, я пишу на многих языках, а с этим наверное надо в С++ тред, но тем не менее - молчать не могу.
Намедни приятель попросил меня поставить ребёнку Minecraft. Ох, какое же говно эта Java - на его ноуте один кадр в секунду. Вообще играть невозможно. Тогда я почти случайно нашёл Minetest - тот же Minecraft, переписанный на С++. И о чудо - графика работает плавно и ничего не тормозиит. Это я ещё не говорю о потреблении памяти, которую Java тупо жрёт как не в себя.
Более того, волею судьбы пришлось знакомиться со всемы модными кластерными технологиями. Заставили на работе. Это, простите, пиздец. Сотни мегабайт ОЗУ и терабайты бесполезных логов. Тысячи TCP соединений между модулями. Накладные расходы на поддержание инфраструктуры могут доходить до 30% а иногда даже и больше. Тот, кто пишет на Си (даже на С++), может понять мою боль.
Думаю, нам нужен мировой кризис, большой кризис, чтобы цены на память, оперативную и дисковую, подскочила до небес. Чтобы смыло всё говно, включая неразработчиков, пиздоменеджеров и ебаные "технологии". Чтобы остались лишь гуру, которые пишут маленькие быстрые надёжные программы.
>>2188348 >Minecraft Ты просто дебил и нихуя не пони маешь. Именно говноджава дала возможность 1) делать моды 2) несмотря на истеричную РРРРЯЯЯЯЯЯ сначала жирного пидора а потом и мелкомягких они все, конечно, утверждали что моды норм и совсем не бомбит - очень смешно выглядит это всё То есть манякампф состоялся исключительно благодаря говняве. Вот такой вот дерьмовый мир. Убей себя.
а че там в С23 пиздатое что-нибудь завезут? если кто знает, плиз краткий пересказ в студию. То лень искать читать эти спеки, я просто любитель хелоуворлды на си пописать не более.
>>2189177 Transactional memory (n1961), асинхронщина на уровне языка (n2017). По мелочи - атрибуты функций теперь будут в стандарте, а не расширением GCC, неименованные параметры функций, decimal типы.
Тред по крестам тонет в бамплимите, поэтому спрошу тут. Я правильно понимаю, что если начну учить кресты, то фактически смогу кодить и на обычной сишке и учебники непосредственно по Pure C НИНУЖНЫ, или это осталось давно в прошлом и после плюсов, если захочу пощупать просто Си, придется листать учебники по нему?
>>2190109 С++ слишком высокоуровневый. Вопреки сложившемуся мнению, что Си мешает учить С++ (а он действительно мешает), ты не сможешь оптимально писать на С++, не зная Си.
Смотри на приложенную картинку. Если извратиться, то на С++ можно писать без указателей. И новички неосознанно это делают. Много костылей налепишь, прежде чем поймёшь как это работает.
Короче, если хочешь стать крутым системным программистом, то учи в следующем порядке:
1. Ассемблер(ы) 2. Современный Си. 3. Классы С++ 4. Использование шаблонов С++
И если очень хочется, но не обязательно, то
5. Написание шаблонов С++.
Или иди традиационным сценарием вкатывальщика - учи использование шаблонов и класссы. Но тогда С++ нахуй не нужен, если не понимаешь чего тебе генерирует компилятор. Тогда это ничем не будет отличаться от знания других языков. Будешь, условно, говнокодить и формашлёпствовать.
p.s. Переход с Си на С++ тяжёл, но зато в результате ты сможешь оптимально писать на С++.
>>2190267 >1. Ассемблер(ы) Двачую. А то вырастают люди, не знающие нюансов сдвига отрицательных чисел. >2. Современный Си. А с какого года начинается современный и чем плох C89?
>>2190267 Спасибо. И еще вопрос: нахуя так много учебников? Касается как просто C, так и C++. Видел, как люди успешно вкатывались в язык после одной-двух книг, но также видел мнение, что без чтения минимум 10 штук ты хеллоуворлдщик. Например, если у C я решу пройти K & R и, возможно, Прату после него, то что я потеряю если не буду читать остальные книги из шапки? То же самое с крестами - неужели Липпмана, Праты и Шилдта будет недостаточно? Опять мнения разделились и кто-то говорит, что после одного только Страуструпа для ньюфагов успешно работали над сложными проектами и вообще стали профессионалами в языке, а кто-то говорит, что это только примитивная база, которой недостаточно, и нужно еще штук 20 книжек прорешать.
>>2187992 Почему в конце нет endl? Я что, как долбоеб, должен смотреть на апельсинарбузвишняклубникаананаспомидорanon@pc123:~/codefrom2ch$ _ ? Алсо, нахуя false через функцию возвращать, и вообще нахуя вот это вот с ифом? enum, кстати, вообще не используется.
>>2191188 И ещё вопрос: нахуя так много лекарств? Видел, как люди успешно вылечивались после одного-двух, но также видел мнение, что без долгой терапии минимум 10 таблетками ты помрёшь. Например, если я решу выпить кетопрофен и, возможно, азитромицин, то что я потеряю если не буду пить остальные таблетки из ЖНВЛП?
>>2191188 Идеальных книг не существует, анон, потому что у каждого свой бэкграунд, и могут быть как пробелы в знаниях, необходимых для усвоения нового материала, так и "лишние" знания из других источников, из-за которых некоторые главы книги будут скучными. А пишется книга не для тебя, не для меня, и даже не для ОПа, а для десятков тысяч студентов. У тебя никогда не было чувства, когда тебе кто-то что-то неравнодушно объясняет, что этот чел умнее любого хорошо продаваемого автора? А он всего-навсего лучше попадает в твои слабые места. С книгами же придется выбирать. Либо берешь хардкорное чтиво и активно гуглишь непонятное, либо берешь исчерпывающий томик на 1000 страниц и пропускаешь хорошо знакомое, бегло ознакамливаешься с частично знакомым и вдумчиво останавливаешься на качественно новом материале. А такое избыточное разнообразие естественно при свободном (да-да, "свободном") рынке. ИМХО, прям от корки до корки, как первоклассник, читать надо ровно до тех пор, пока не начнешь комфортно плавать в области, а там уже сам разберешься, где хороших практик подсмотреть, где про матчасть какой-то штуки полистать и т.д. и т.п.
Аноны, а что думаете о книгах/учебных пособиях издательства O'Reilly? Конкретно: Head First C: A Brain-Friendly Guide. Реддиторы её регулярно рекомендуют новичкам. Как для совсем ретарда, который ничего сложнее примитивных баш и питон-скриптов не писал - не лучше вариант, чем то, что в шапке?
>>2189177 Обещают завести лямбды и typeof. Может хоть теперь можно будет воспользоватся макросами нормально. >>2190811 Тем что там по крайней мере завезли нормальные типы целочислиных с нормальным размером, restrict, анонимные структуры и юнионы, static assert. Есть ещё потоки, но они нигде из коробки не работают.
>>2192494 >Лямбды и typeof В принципе смотрю добавляют все то, что в gcc было сделано расширениями. И эти штуки не исключения. Можно сделать лямбды на базе gcc nested functions и typeof в си через расширение там тоже есть.
>>2192834 Дело в том что обычные вложеные функции требуют либо костыль, который отключает no execute бит, либо менять ABI. Ну или можно а) никогда не брать адресс функции б) не использовать в фунции адреса внешних функций Лямбды какбы обходят это. Плюс анонимность лямбд полезна при написании макросов или когда надо отправить одну фунуцию в qsort. Вообще об этом можно почитать здесь https://medium.com/program-practical/blocks-procs-lambdas-oh-my-8c636a54757c
Аноны, привет Хочу подключиться к порту динамика и работь с ним как с потоком, то есть я посылаю какую-то частоту и она воспроизводится через динамик. Все это я бы хотел сделать используя язык Си на Windows, не подскажите как это сделать или можете скинуть литературу, статьи или другие формы источников, а то я пытался найти решение как на русском, так и на английском, но ничего не нашел, буду очень Вам благодарен.
>>2200838 Можно использовать http://sox.sourceforge.net/ И никакого winapi не потребуется, тупо в stdout писать отсчеты и всех делов то, проще некуда. Но это конечно смотря для чего тебе все это нужно.
>>2200851 Не ебу, что ты хочешь. Для винды есть wasapi, directsound, winapi, плюс сторонние либы. Ты хочешь типа вывод на аудио перенаправить? Чтобы писать write(fd,buf,c)?
>>2201554 на плюсы проект переводить никто не будет, а вот повысить стандарт с 89, который сейчас используется, до 99 - это возможно. Поэтому и спрашиваю
>>2201554 Учусь в ВУЗ'е и я дегенерат, почти не шарю за языки, почему все так хвалят ООП и С++, если это говно лютое, говорят, что код легче писать, чем в структурном программировании, но типо все равно же если какую-то деталь меняешь/добавляет код переписывать нужно?
>>2201514 В msvc поддержки c99 почти что нет, поэтому вулкан должен работать и с c89 >>2202402 Абстракции легче строить. Попробуй фп, там похожие ощущения, и не потому что не надо думать о модели памяти, а потому что абстракции строить и поддерживать проще и удобнее. В низкоуровневых апи, как вулкан, много бойлерплейта, от которого можно частично избавиться с помощью абстракций. >>2202404 Какие охуенные фичи? ub?
>>2202449 > В msvc поддержки c99 почти что нет, поэтому вулкан должен работать и с c89 да в msvc уже давно C11 завезли сейчас проверил покомпилить с vulkan, там все комменты в стиле C99 написаны, поэтому как минимум их придется тогда менять во всей либе, глубже пока не раскапывал
>>2202449 Всех особенностей языка, ну, могу немного работать с паматью, но вот на потоках(если не считать работу с бинарками и текстовыми файлами) остановился. Как кстати узнать свой уровень владения языка?
>>2204526 Почему уничтожающих? Наоборот, подробно расписывают один из самых крутых механизмов языка. Если ты его не осилил, это ещё не значит, что си "уничтожен".
>>2205060 >пердуина Твоя дурина это AVR (а они далеко не все на AVR)? >усрется сдвигать Если у тебя AVR и ты загрузишь свои 6 байт в uint32_t, а потом сдвинешь на один бит вправо, то получится примерно вот такая последовательность команд: lsr r1 ror r2 ror r3 ror r4 Номера регистров конечно могут быть другими. Каждая из этих команд выполняется за один такт. Ну и поскольку тебе нужно сдвинуть на три, то эта последовательность будет повторена три раза, может быть в цикле. Итого ну максимум тактов 20 в худшем случае, не считая загрузку-сохранение. Ахуеть как много! Да у тебя на загрузку одного байта из ОЗУ тратится три такта.
>>2205060 Не знаю почему ты решил что сдвиг это сложная операция, но разрешите доебаться. Чтобы отбросить три десятичных разряда действовать нужно нихуя не сдвигом.
>>2205079 Разделить на 1000, это ты правильно догадался.
Кстати я раньше думал что пердольщики микроконтроллеров это такие суровые байтоёбы, думающие шестнадцатеричными дампами. Но ардуино-тред и обсуждения на других форумах развеяли это заблуждение и чуть не погасили веру в человечество вообще. Теперь я просто задаюсь вопросом как у вас в принципе хоть что-то работает.
>>2203653 Ну и чтиво, конечно... Помню, как-то сам напоролся на strict aliasing с полями структуры и кастом в void, если не изменяет, и анон итт посоветовал мне не страдать хуйней, если не >знаешь что делаешь и умеешь в -fstrict-aliasing но я с самоуверенностью Даннинго-Крюгернутого продолжал пукать в ответ на критику UB. Теперь стыдно стало. Прости меня, двачик, за нехорошие слова.
Бля, это внатуре пиздец какой-то. Есть какой-то гарантированный набор флагов, который исключит всю эту хуету и заставит программу вести себя так, как я думаю?
Блядь, да вы ебанулись, идите нахуй с таким Си ебаным, воистину лучше уже вернуть совок и посмотреть, какой ЕГЯП (единый государственный язык программирования) сделали бы, чем такие приколы.
>>2205149 А здесь попробуй вычесть единицу, а не прибавить. Но никто тебе не гарантирует что указатели будут лежать рядом. Ебаный компилятор может их положить как угодно в стеке, как он сочтёт нужным.
А вычесть вместо прибавления потому что стек растёт в сторону уменьшнния адресов.
>>2207236 А в чем прикол? В том, что по наивному ожиданию результат будет 4 независимо от порядка выполнения первоочередных выражений с их сайд-эффектами? Сайд-эффект же, вроде, вообще не обязан выполняться до ближайшей запятой или точки с запятой?
нуб в треде. а если malloc вызвать внутри функции и передать указатель на этот участок памяти из этой функции то будет ли эта память защищена от изменений или это UB?
Можно ли как-то с помощью макросов или иной магии сделать так, чтобы расширять enum из разных точек программы.
Например, есть изначально enum alpha { A = 0, B = 1} и вот чтобы в какой-то точке программы вызвать какой-то магический макрос, чтобы оно уже было вида скажем enum alpha { A = 0, B = 1, C = 2}
Вроде как это технически нереализуемо, но может все же я что-то не учел.
Функция getenv() возвращает указатель на данные о среде, которые хранятся в строке, адресуемой параметром name в таблице характеристик среды, определенной конкретной реализацией. Ваша программа не должна изменять значения, хранящиеся в этой таблице.
Среда программы может включать такие данные, как пути и подключенные устройства. Формат данных определяется конкретной реализацией, поэтому для уточнения деталей необходимо обратиться к руководству пользователя, прилагаемому к компилятору.
Если при вызове функции getenv() значение аргумента не совпадает ни с одним из данных в описании среды, возвращается нулевой указатель. Пример
Предположим, что определенный компилятор поддерживает информацию среды относительно устройств, подключенных к системе, тогда следующий фрагмент возвращает указатель на список устройств:
>>2165466 (OP) Хочу считывать из stdin самый свежий символ. При этом после того как считал записываю null чтобы если пользователь ничего не нажал я в следующем вызове в ответ получил null и ждал пока он таки сделает ввод. Но оно почему-то не записывает null, или я читаю не самый свежий ? Помогите пжлст
>>2214240 >>2214238 почитал интернеты. Походу действительно нельзя. Тогда буду сдвигать чтение на 1 влево и проверять совпадает ли текущий с предыдущим. Если не получится выйду на связь
Аноны, привет. Месяц как вкатился в си (первый яп), но на указателях понял что нихуя не понимаю как работает компьютер и на решении банальных задач (codewars, etc.) не могу продвинуться дальше. Можете посоветовать чтиво по компьютерам в целом, или что сами паралелльно читаете си?
>>2214375 > но на указателях понял А чего всех так пугают эти указатели? В свое время изучал си как первый яп по базовому курсу c++ от шилдта и все было ясно с первого раза. Может тебе лучше в python?
>>2214375 Ну вот у тебя есть ящик, в котором ты можешь хранить утюг. Сам утюг в этом ящике - это значение твоей переменной. А номер на ящике, чтобы ты его нашел из кучи других ящиков на полке - это и есть указатель.
>>2214399 > Может тебе лучше в python? не советуй каку новичкам
>>2214654 >не советуй каку пока молодые шутливые питонисты получают 300кк дата-сциентистом и ебут сочных зумерш-тестировщиц, сишники пердолятся в срачечку с говнолегаси на пару с петровичем из НИИ-ХУЯ >>2214556 gruvbox-material
>>2214701 >пока молодые шутливые питонисты получают 300кк дата-сциентистом и ебут сочных зумерш-тестировщиц, сишники пердолятся в срачечку с говнолегаси на пару с петровичем из НИИ-ХУЯ Пиздец, что ты с таким мышлением в Си-треде забыл, болезный? По твоей логике обычный васян или хач, которые по КД солевых шмар ебут - это высшая стадия человека и предел мечтаний.
Микроконтроллеры С stm cmsis
Джорно17/11/21 Срд 19:02:10№2215253253
Я учу embedded на си без hal на чистом cmsis посоветуйте
а вот если допустим объявлена в коде структура A дальше по коду можно как-то макросами/директивами чекнуть объявления ли она? типа: #ifndef A printf("NO"); #endif
>>2215517 Нет, макросы раскрываются препроцессором, который кроме лексического анализа и некоторых преобразований ничего не делает
Но можешь оформить заголовочник подобным образом: #ifndef STRUCT_A #define STRUCT_A struct A; #endif а потом уже в коде: #ifndef STRUCT_A printf("NO"); #endif
>>2216267 Подождите, mutex нужен чтобы определенный участок кода мог выполняться только из одного треда. Зачем мне статический объект mutex'a ?Я должен что-то с ним делать из другого?
>>2216327 т.е ты хочешь сказать что auto mutex это бред т.к, если я запущу два треда на эту функцию, будет 2 отдельных не связанных между собой mutex'a. Ну ок, звучит логично, пойду поправлю
почему для билда програми обычно юзается мейк либо какая-то петушиная херна поверх мейк. почему нельзя тупо в башскрипте накидать билд скрипт который соберет проект?
>>2217577 А потом ты в своём проекте из миллиона файлов поменяешь один .c-шник, и твой петушиный скрипт либо обосрётся и будет заново всё пересобирать, либо обосрётся и ничего не будет пересобирать, бинарник вот же он, готовый лежит.
>>2217577 > почему для билда програми обычно юзается мейк потому что это стандарт такой по умолчанию, чтобы везде люди могли собрать его под любую ОС и чтобы синтаксис все знали поэтому сейчас пишется только CMakeLists.txt, а все остальное уже само делается под нужную систему: хоть яблоки, хоть андроиды (да, они тоже уже на make как альтернативу перебрались)
навернул тут control-flag и вспомнил про cppcheck. у меня и в прошлый раз была проблема с ним - он не видел хедеры в системе чтоли, не понял. так вот снова:
он скипает файлы натыкаясь на #error в #if отложенных на всякий случай. This file is not analyzed. Cppcheck failed to extract a valid configuration. The tested configurations have these preprocessor errors: я даже свежий скомпилировал - всем похуй или проблемы на самом деле нет (/решается)? но я вроде прочитал хелп.
может есть что-нибудь пободрее, но без платы шекелей? а контрол кстати плотный тул, ни одного фелзпозитив не словил ещё.
>>2218407 и как это обычно бывает, сходу решилось. не увидел что у этой ошибки есть тег, по которому можно заигнорить. я думал что это и не ошибка даже, к тому же в хелпе: Suppress a specific warning.
>>2218428 потыкал ещё и похоже упёрся в то, что и прежде. например, у меня много проверок на случай если какого-то типа нет или он не того размера - #error. cppcheck не видит объявления необходимых, а подбирает как-то по особому сочетая, как если бы это были опции компиляции. нужно инклюдить хедеры, но от -I/usr/include/ -I/usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include/ , ему ещё больше сносит крышу (в частности от sdl). остаётся только точечно: --include=/usr/include/limits.h --include=/usr/include/assert.h --include=/usr/include/stdint.h --include=/usr/lib/gcc/x86_64-pc-linux-gnu/9.3.0/include/stddef.h. и то, это принудительный инклюд в каждый файл, что как-бы не очень хорошо. и конечно, встаёт вопрос: а нахуя мне всё это надо и к чему это приведёт?
Кстати, а что мешает в С ввести в каком-нибудь новом стандарте обобщенной программирование? Синтаксис там элементарный, ничего не ломается при этом, шлепается легко поверх старого кода. Ну имеется ввиду не то, что там этот _Generic ввели, а хотя бы уровня слизанного с плюсов (или даже выше)
>>2219043 > Что тебе не так с _Generic? например, нужно реализовать библиотеку для векторов, ну что-то аналог STL, сейчас есть вариант только накрутить это все через макросы в очень неудобном виде, что нужно в стороннем коде при использовании этой библиотеки для создания вектора своей структуры: 1) задекларировать такой вектор 2) объявить переменную для такого вектора 3) инициализировать вектор и потом уже очень неудобно работать
ну теперь пробуем применить _Generic, как написать через него вектор произвольного типа с общим поведением? Допустим какие-то мы объявили в этой библиотеке, ну а пользователь в своем коде что должен делать?
>>2219215 > Используем магию ## ну это и был единственный, но очень кривой вариант, для написания подобной либы у нас, но чтобы оно работало через синтаксис макросов в этом виде - уж больно много ненужного хлама дополнительно генерится в асм выхлопе, поэтому и был такой крик душа, что когда уже.. деструктор бы еще, ну хоть defer может все же скоро завезут
>>2219083 не знаю что там в stl (поэтому возможно пишу глупости), но вектор (геометрический) специфичная же штука. вот например у меня 16 бит на дробь и 16 на целое, как поможет то, что я его объявлю типом long? остальное же: списки, очереди - они не зависят от типа.
Привет, аноны, пришел к вам за помощью. У меня имеется 300-350 бинарных файлов весом по 300мб каждый. Необходимо распарсить эти бинарники и записать в большую таблицу для дальнейших преобразований(с парсингом я офк справлюсь и сам), но вот с большими файлами я не работал. Если писать все данные в кучу, то у меня не хватит оперативы. Как изьебнуться и обьединить все 300 файлов в одну таблицу, при этом нагружая оперативку в разумных пределах?
>>2219365 Ну вот смотри, например, у меня есть слой(таблица из 100 записей) и я их занесу в буфер. Допустим, что таких слоев в файле 10, которые я буду записывать в буфер по мере необходимости. Мне нужна возможность переключать эти слои в двух направлениях(представляю как реализовать), а как быть после простотра последнего слоя в файле? Тупо переключать файловый поток на следующий/предыдущий файл? Или же есть более трушное решение.
>>2219364 >nmap Вот это уже выглядит ближе к теме, пойду курить маны.
>>2219280 > не знаю что там в stl, но вектор (геометрический) специфичная же штука да, речь шла про вектор как один из видов контейнеров (например, vector в C++)
Как можно подключить библиотеку скаченную с гитхаба? Как скомпилировать чтобы всё заработало? На линуксе. У меня ubuntu. Я бы хотел скачать библиотеку GUI лёгкую, простую, и сделать простую программку, скомпилировать её под windows также.
Знаю Си, кодирую пока что простые проги и алгоритмы изучаю. Собираюсь после уверенного знания Си перекатиться в кресты, алсо решаю задачки и т.п в общем применяю на практике алгоритмы. Вопрос господа: У меня аттестат среднего общего, везде требуют блять высшее и минимум год работы и неебические знания. Как найти работку чтобы набраться реального опыта? Мне пиздеть в резюме? Посоветуйте анончики что делать та. Может написать какие нибудь проги в портфолио, или на гите искать работу? ДС2 23 годиков. Вообще хочу игры кодить, но есть желание в будущем системками заниматься.
Простите за ебанутый слог я сейчас в тяжелом положений. Если можете направить куда нибудь где объяснят как искать работу в любимой сфере деятельности буду признателен. Я просто хочу сидеть и кодить сутками.
>>2222840 Слишком размыто ты написал. Какие задачи решаешь, какие алгоритмы изучаешь? В какую сторону планируешь развиваться? У меня ощущение, что ты фундаментальные вещи сейчас учишь, не более. Неебические знания включают в себя, например, анализ сложности алгоритмов, всякий разный матан, короче, то, что учат в вузиках. В принципе, это можно и самому освоить, но будет сложно. И да, пиши сразу на крестах, выучишь ооп, научишься всякие шаблоны проектирования делоть.
>>2222849 Именно так, база. Хочу поступать на физмат, но нужно работать. Алгоритмы очень базовые, а еще всякие ADT. Закончил Пратовский учебник и сейчас тонкости языка изучаю, а еще либу стандартную ну и дебагер. Алгоритмы по известной книжке пытаюсь писать сам на Си, на c-faq нашел много инфы, но вот практический опыт надо где-то брать. Спасибо анонче, буду кресты изучать.
>>2222852 >физмат Это если ты потом хочешь в машоб идти, речёрчами заниматься или еще что-нибудь матаноёмкое. Ну скажи, нах тебе, программисту, знать функциональный анализ или какие-нибудь сплайн-аппроксимации? Если пилить игры, то это пригодится для разработки движков, что весьма специфично при наличии тонн готовых. Если системное программирование - тебе нужны знания об архитектурах, ассемблерах и битоёбстве, что на физмате тоже не очень хорошо изучается. Тебе матан или ехать все-таки?
>>2222872 А на кого мне пойти учиться в вузе если я в геймдев пойду? Дико интересно было кодить симуляции с кружочками и платформеры. Какой нибудь software engineer? Посмотрю сегодня еще раз опции в МФТИ. В любом случае если в будущем будет интересно продолжить изучение матана, уже хотя бы будет понимание. Программировать дико интересно. На данный момент у меня 9 классов в 23 годиков и в этом году хотел закончить школу экстерном, но материала оказалось много особенно по математике, в этом году собираюсь все догнать хотя бы до линейной алгебры и в следующем сдавать.
Адекватна ли подобная практика, не нарушает какой-нибудь strict aliasing rule? Переданный в loop() указатель на user передаётся в handler(), и я пытаюсь через этот указатель структуру передать. https://pastebin.com/PvKsrJY3
кто шарит за драйверы в линукс? Пишу драйвер блочного устройства
Как зарегистрировать драйвер на шине в sysfs? Как зарегистрировать устройство на шине в sysfs? Реализовал ioctl интерфейс, как теперь обращаться к нему в запущенном драйвере? Отправлять команды?
>>2225495 Спасибо, всё работает как надо, правда компилятор ворчит на incompatible pointer type, потому что коллбэк должен принимать unsigned char звёздочка первым аргументом, a loop() - последним. По логике можно игнорировать, но напрягает немного.
Сильно ли плохо, если я в Си сделаю структуру с функциями в качестве мемберов, для некоего подобия "классов"? Ну, фактически прсто соединю функицю-обработчик и передаваемые ей данные в "стандартизированном" формате, для как бы интерфейса? Типа вот такого — https://ideone.com/GaxwyK ?
>>2165466 (OP) Задаю тупые вопросы. Правильно ли я понимаю, что если мы создаем типа динамический массив, потом переопределяем его размерность, то он может перезаписать информацию, которая могла уже быть записана по определенным адресам идущим после него, или же он переопределяет новый пул адресов и каким-то образом переносит массив?
>>2225642 Не, мне не столько ООП нужно, сколько просто возможность собрать несколько однообразных функций и данных в массив для итерации по нему в "общем" коде.
Например, есть устройство с каким-нибудь колесом, лампочкой и звуковым сигналом. После какого-то события нужно их все включить (процедура включения, допустим, сложная, а не напряжение на пине поменять в одну строку). Но есть точно такое же устройство, в котором нет лампочки, а в остальном логика идентичная. Вот "общий" код отвечал бы за, собственно, обход связного списка "контроллеров", созданного/инициализированного в коде уже конкретного устройства.
То есть, хочу избежать кучи ifdef'ов типа >enable_wheel(); >#ifdef HAS_LIGHT_INDICATION .>enable_light(); >#endif >enable_sound();
>>2226039 Засунь ифдеф внутрь enable_light(). А компилятор потом повыкидывает пустые функции. В твоем варианте ядру придется перезаписывать pc, сбрасывать конвеер и ждать, пока новые инструкции поступят на исполнительные блоки. Хотя если производительность не важна - то пох.
Есть такая строчка в массиве { "faststart", "Run a second pass to put the index (moov atom) at the beginning of the file", 0, AV_OPT_TYPE_CONST, {.i64 = FF_MOV_FLAG_FASTSTART}, INT_MIN, INT_MAX, AV_OPT_FLAG_ENCODING_PARAM, "movflags" },
Что в ней блять значит {.i64 = FF_MOV_FLAG_FASTSTART}? Это должно стандартное значение. В другом файле нашёл #define FF_MOV_FLAG_FASTSTART (1 << 7) Сдвиг единицы на 7? Как такое возможно если параметр по умолчанию выключен? И что значит .i64? Почему к нему обращаются с точки?
>>2227136 >#define FF_MOV_FLAG_FASTSTART (1 << 7) Это значит, что везде, где ты видишь FF_MOV_FLAG_FASTSTART на самом деле подразумевается (1<<7), т.е. 128.
>Как такое возможно если параметр по умолчанию выключен? Кто выключен? Этот дефайн — это просто способ дать какому-то числу название (для понятности), не вводя переменных. То, что faststart по-дефолту не исопльзуется будет влиять лишь в процессе работы, где ffmpeg пропустит какую-то часть кода, а у тебя в этой строке лишь описание выставляемого флага (который и будет проверен далее).
>И что значит .i64? Почему к нему обращаются с точки? Вероятно, там union, поэтому указывают, какому именно варианту значение дают. Типа вот так — https://ideone.com/z2loWI
Хотя можно и просто структуры инициализировать с именами мемберов, даже в любом порядке — https://ideone.com/GVMe42
>>2227432 У одних есть заголовок перед тем адресом, который тебе вернули. У других есть таблица страниц, которая говорит, на какие равные куски разбита страница.
Знатоки, внимание, вопрос! Вот я создал массив на десять элементов, arr - это же получается указатель на 0 элемент. Так вот, почему в main тогда sizeof(arr) указывает 40 байт? Я понимаю, что это размер всех элементов внутри, но почему тогда в функции in sizeof(arr) равен 8? и там и там же указатель...
https://pastebin.com/ZGSwgY73 Что я упускаю? Мне нужно в определённой структуре хранить представление целого числа в форме последовательности байт, размер числа будет храниться в ней же. При этом при попытке преобразования происходят вот такие приколы.
>>2227893 Перед сдвигом uint8_t приведи его к типу uint64_t На signed вообще забей - приводи его к unsigned. В твоём случае это роли не играет. Твой код не учитывает big_endian и low_endian - при портировании на другие архитектуры получишь сюрпризы.
И вишенка на торте - раз ты забил хуй на endianness, то и циклы не нужны - достаточно поиграться с указателями и приведением к типу. Ещё и в 20 раз быстрее работать будет с тем же самым результатом.
>>2229507 >пикрил Да, как-то делал на нодежс одну прогу впервый раз, и надо было получить текст из клипборда. Вместо того, чтобы вызвать нативную функцию винапи за микросекунду, эти уроды выложили в этот говностор приблуду, запускающую павершелл, потом в нем команду и берущую её результат. Еще бы блять вставили компиляцию винды из исходников сначала, что размениваться на мелочи.
>>2165466 (OP) Возможно ли перекатиться в США/Европу/Китай, будучи Embedded-программистом? Я понял, что эта тема - наиболее интересная для меня из всего айти, к тому же, когда я только начинал заниматься программированием, я уже знал, что кодить можно под микроволновки/чайники/переносные устройства, и хотел заняться чем-то подобным.
>>2227893 такие вещи делаются через union вообще то.. неужели это настолько сакральные знания стали а я типо мамонта-дурачка который еще что то там бормочет для вкатывающихся школьников..
>>2226039 лучше придерживайся правила "не обобщай до пяти" то есть для каждого случая пиши новый код а когда таких случаев будет больше пяти то уже пытайся выделить общий код
>>2225637 все компонентное программирование (com, gtk, и десятки других библиотек) на этом и основывается ты идешь по тропе протоптанной десятками тысяч программистов до тебя но тебе кажеться что это дикий первозданный мир
>>2230989 нет, ты просто тупой, если делаешь это через union.
>>2227893 как-то вспомнился вопрос с рсдн лет десят назад: а зачем вы нижнее подчёркивание добавляете перед именами функций? - и я до сих пор не знаю, зачем это делают пользователи
>>2225637 >>2230994 это просто современность испортила людей, подкладывая им в постель идеологов современных стилистик полового сношения. вот и приходится робко открывать для себя, что член структуры указатель на функцию - это не ооп.
да я и сам после полугода плюсов и пересевши на c (заебался определять что чей метод), удивился, насколько всё просто и что совершенно не обязательно ебать себе мозги.
>>2231011 >нет, ты просто тупой, если делаешь это через union. с хуя ли? если видишь что прогер работает с внутренним представлением чисел через смещения а не через объединения - это сразу признак низкой квалификации
>>2231477 -O3 в некоторых случая может порождать более медленный код, поскольку всё что можно разворачивает и инлайнит, вследствии чего плохеет кэшам проца и может быть деградация производительности. Не обязательно это случится, но может быть. В зависимости от того, что именно ты компилируешь и как это написано. За остальные ключи ничего не скажу - у меня не было необходимости выжимать такты из кода. Предпочитаю поднимать скорость алгоритмами и стилем написания кода, это несложно, если ты понимаешь ассемблерный код, генерируемый компилятором.
Ну а ежели ты занимаешься "числодробильными" задачами, типа матмоделированием, то не пользуй gcc, а возьми компилятор от Intel - он заточены как раз под оптимизацию больших вычисленй.
>>2165466 (OP) Приветствую всех присутствующих. Сейчас пишу курсовую по программированию. Gentoo, CodeBlocks, GCC. После внезапного аварийного завершения работы компа во время редактирования кода (в компе нет батарейки, а шнур от зарядки такого говённого качества, что любое резкое движение может вырубить комп) программа вообще перестала компилироваться. Когда я в CodeBlocks нажимаю "собрать и запустить", выдаёт пикрилы. Причём если я команд, указанные в логе, ввожу непосредственно в консоль - всё компилируется нормально. А если я то же самое делаю через кодблок - нихуя, файл .o почему-то не создаётся. Что делать?
>>2232705 Отладь в Visual Studio, что ты как маленький. Наверняка же у тебя консольная программа, которой похуй - Windows или Linux. За исключением маленьких нюансов.
Вопрос один: Вот понял я как работают указатели в C, и отсюда возникает вопрос, как в более высокоуровневых языках где нет указателей, компитятор/интерпретатор понимает, где идет речь о значении, а где о адресе? Вопрос два: Была такая проблема: выделяю память динамически через malloc в программе, компилирую используя gcc i686 4.8.4, запускаю - все заебись. Далее беру тот же код, компилирую через gcc x86_64 4.8.4 - компилируется нормально, запускаю, ввожу тот же тест и получаю Segmentation fault (если заменить динамическое выделение памяти на автоматическое, то ошибка пропадает), и так не только с одним тестом, а в целом скомпилированная одной и той же версией компилятора, но под разные платформы программа просто не работает нормально. Загуглив, что такое i868 я нихуя не понял, челы с stackovwerflow пишут, что это просто разновидность x86, зачем тогда существует отдельная версия gcc под нее? правильно я понимаю, что я могу и то, и то использовать на 64-х битной системе?
>>2233638 >компитятор/интерпретатор понимает, где идет речь о значении, а где о адресе? ну там же есть понятие объекта и способов к нему обращаться.
> Вопрос два: это не один вопрос.
> Далее беру тот же код, компилирую через gcc x86_64 4.8.4 - компилируется нормально, запускаю, ввожу тот же тест и получаю Segmentation fault хз, может ты это делаешь на 32хбитно системе.
> что это просто разновидность x86, зачем тогда существует отдельная версия gcc под нее? это не отдельная версия, а отдельный билд.
> правильно я понимаю, что я могу и то, и то использовать на 64-х битной системе? нет. можно, если ос имеет к поддержку (библиотеки 32хбитные и какую-то там совместимость - в теории)
>>2233638 >компилируется нормально, запускаю, ввожу тот же тест и получаю Segmentation fault Классическое описание undefined behaviour. Ищи, где объебался, ворнинги компилятора, ub sanitizer и valgrind в помощь.
скармливаю любой пример из задания. например: 11111 19991 19191 19991 11111 то на 6 степе валится сегфолт. если дебажить то на выходе из функции octos_next_step дебагер ругается > Cannot find bounds of current function я так понимаю стек закораптился, но я не понимаю почему. У меня там рекурсия, но поидее это не должно влиять, там не так уже и много вызовов рекурсивных должно быть.
>>2235569 бляааадь, а с чего я взял что так можно писать? кажется фляга уже совсем свистит. Пожалуй сегоня без компа проведу выходной. Спасибо, братик. Я реально хз откуда я это высрал. Ну дела, конечно.
>>2235590 > Взвизгнул. а что, сильно все хуево кроме этой залупы 0<nrow<rows?
> Автор, чому ты намешал все фишечки С11, не усвоив БАЗУ из книжки K&R? Я хз, я си еще давно в универе учил, тогда мне не зашло, на отъебись его тогда сдал. Не так давно решил узнать, что в си нового, да и старое вспомнить. И вот как-то так вкатился заново уже с новыми фишками языка. За K&R я как-то сел , но не вхатило терпения что-ли. В сотый раз читать про что такое тип, переменная, функция супер скучно.
>>2236073 А нахуя там ub делать? поч не дать считать как с указателя и получить вылет? Буквально вместо падения приложения делают тихое игнорирование..
>>2236103 Что "делают", дубинелло? Если твое число как адрес случайно указывает в наличную память, оттуда что-то будет прочитано как строка. Если нет - вылетит.
>>2236148 ну так, то что ты написал - понятное мне поведение, а выше чел писал что это UB. Вообще я не подумал, наверн чтение мимо это тоже UB, тогда тут все очевидно. Я сначала решил, что там какой-то специальный случай UB для va_args, типо ожидет строку, а передает int, и компилятор хуйню придумает. В примере 1ого чела не вылетело, а у него число 5, какбы сомневаюсь что на 5 там можно читать ему.
>>2236212 предполагаю, что printf когда доходит до %s вызывает va_arg(args, const char*), и так как "If the type of the next argument in ap (after promotions) is not compatible with T, the behavior is undefined" (цитата с cppreference - C docs). Поэтому UB. Реально же (не по стандарту, но на обычном компе), va_arg тупо копирует со стека столько байт, сколько было бы, если бы там был указатель. На x64 у тебя скорее всего в int'e 4 байта и в указателе 8 - ты получишь указатель, который наполовину будет 5, наполовину - мусор со стека.
>>2236226 а? не понимаю твой текст. Я конешн на Си никогда не писал, но про указатели и литерал строковый знаю из плюсов. На пике cppreference (раздел про Си), пишет что ожидается указатель на char, какие вопросы?
Как на этом блядском языке нормально хендлить инпут пользователя? Пытаюсь написать консольный калькулятор и столкнулся со следующей ошибкой, когда я делаю scanf("%d",operation), то если пользователь введет, допустим, 1B, то в переменную operation считается 1 и scanf вернет 1 мол все ахуенно прошло, но у меня-то операция 1 а не 1B. Че делать подскажите вкатуну, с меня как обычно ниухя
>>2236331 >Как на этом блядском языке нормально хендлить инпут пользователя? Как и на всех остальных - читаешь строку а дальше сам думаешь что с таким вводом делать
Есть один STM32 и необходимость записать 8 байт (один uint64_t) во флеш.
Сделал вот так — https://ideone.com/qYkgwU и вроде всё норм работало (gcc компилировал). Это нормально так делать? У коллеги затем (тоже gcc, только другой немного версии и на винде) почему-то работать перестало, и значения *ptr как-то плавно перетекли в 0x5555 после нескольких повторений записи (пока дебажили, почему неправильное значение после азпуска. При этом value остаётся нормальным, т.е. сама память-то вроде правильная, а вот если к этой же области обратиться как к uin16_t — нет.
Что-то я понять не могу, что это вообще такое и почему происходит? Запускается всё на идентичной плате, но у меня почему-то работает (с -O0).
При этом на ideone видна та же самая проблема, ptr выводится мусором. Однако, если я чуть изменю лишь один принт, чтобы и адрес выводил, то всё нормально становится — https://ideone.com/UG7rmg / https://ideone.com/r2kyZW. Что за херня вообще?
>>2236578 >Однако, если я чуть изменю лишь один принт, чтобы и адрес выводил, то всё нормально становится Люблю запах Undefined Behaviour по утрам. Это запах... нуба.
>>2236780 Это я, конечно, провафлил, но этот массив только в примере на ideone существует (чтобы код выполнялся) и к никак делу не относится. На самом деле там адрес флеш памяти указан, естественно. В принципе, это в примере вообще лишнее, для полноты оставил.
Вот тут пару вариантов протестировал — https://ideone.com/Ph67mH >uint16_t u16_2 = (uint16_t)&value; Выдаёт правильное значение. А вот >uint16_t ptr = (uint16_t)&value; >*ptr Уже нет. Я не пойму, в чём разница между этими двумя вариантами, кроме того, что во втором случае на две строки разделено?
Как только я пытаюсь вывести адрес value или значение указателся ptr, чтобы убедиться, что они действительно на одну точку указывают (мало ли там с alignment'ами что), всё магическим образом начинает работать. Будто тут какая-то квантовая физика с суперпозицией.
Может такое быть, что uint16_t ptr указывает на, скажем, 0xff00, а ptr+1 будет не 0xff02, а 0xff04 по какой-то причине? И даже если такое возможно, первые два байта-то уж точно же должн читать правильно? Да, указатель может указывать как на начало, так и на конец области памяти, вроде как, но ведь изначально они оба указывают на одну точку, до инкремента ptr'а он обязан взять те же данные, что в value записаны, разве нет?
>>2236806 Точнее, как можно увидеть по ссылке, до цикла значение ptr'а выводится правильно, а вот в первой же итерации, до всяких манипуляций — нет. Обзывайте меня как угодно, только объясните, пожалуйста, что происходит.
>>2236823 >ptr может быть 64 бита, а ты кастуешь на 16 битный указатель. В смысле? В прошлом сообщении макаба сожрала звёздочки, я нигде 64 бита в 16 бит не кастую. Сам ptr имеет размер указателя, но указывает он на переменную типа uint16_t.
Возможно, проблема из-за "dereferencing type-punned pointer", gcc на сайте даже ворнинг выдаёт. Раньше читал, но до конца толком не понял, что это такое. Ну, кроме того, что "нельзя" одну и ту же область указателями на разные типы читать. Только если не char•, там можно почему-то. Вот только почему идентичный принт на разных строках до изменений переменной выдаёт разный результат это не объясняет. Раз уж ломается, почему так выборочно?
>>2236903 Добавлю: с O1 также, с O2 выводит нули, с O2 и "-fno-strict-aliasing" выводит правильно. >>2236840 >"dereferencing type-punned pointer" тут ты прав скорее всего
>>2236868 > Я тебе пидор что сказал, заменить типы на дефолтные, а ты что сделал? А чем short не дефолтный?
> Вот так правь и уебуй > typedef unsigned long long int uint16_t; С чего это uint16_t будет long long? Сделав uint16_t == uint64_t, понятное дело никаких проблем при кастах и возникнуть не может, потому что они просто ничего не делают, типа идентичны. Сам-то вообще понял, что сделал, заменив все типы на один и тот же?
В STM32 запись во флеш идёт только по half-word'ам (16 бит), так что мне нужен был именно 16-байтный тип. Т.е. строка >٭(uint16_t٭)addr = data; В любом случае будет, и если эта data другого типа, то опять проблемы могут появиться. Суть моей задачи была разделить 64 бита данных на 4 16-битных куска и позаписывать их в память. Теперь-то я, конечно, переделаю всё на простые сдвиги без подоных алиасингов, чтобы точно правильно работало.
>>2236927 >В твоем случае если бы ты использовал стандартные инты то было бы проще, ну или заморочился с кастами. Как я могу использовать int в 32-битной системе для переменной, которая должна хранить 8 байт?
>>2236990 Что значит не должна, с чего ты это взял? У меня есть 64-битный айдишник, который я получаю откуда-то там, и вот с ним дальше работать. Это начальное условие задачи, что есть 8-байтная переменная с данными.
>>2236960 Ну можно и так, но через юнион проще тогда сразу на uint64_t и uint16_t [4] делить, инты эти мне совсем не нужны.
Пацаны, помогите. Короче, есть одна проблема. Нужна копия массива на этапе компиляции. Масив генерируется из matlab .h файла(весь контент через #define). Как это сделать?
Просто из матлаба это грузится в мк, где это инит конфигурация, которую надо сверить правильно ли загрузилась. Я долбоёб и без плюсов constexpr контейнеров не умею.
>>2237104 Не собрался я копировать масив в макросе. У меня есть .h файл, куда матлаб сбрасывает готовую глобальную переменную массив. Но мне нужна копия этого массива, так как эту переменную как только пройдет 10 мс микроконтроллер изменит и мне надо сверить что изменилось(должно быть также).
Срака в том, что я не могу узнать даже в каком месте поставить memcpy() чтобы копировать в другую глобал переменную, у меня нету кода места записи этого массива, кудя я бы захуярил этот memcpy
>>2237244 Заебца, так и сделаю на питоне хуёне скрипт и в makefile скопирую это говно. >>2237139 Ну это я и раньше понял, >>2237117 Идея неплоха, но каждый раз там хуй знает сколько символов и всегда меняются названия.
Здравствуйте уважаемые. Есть распбери 3б+. Мне нужно принимать данные с ацпшки(10 бит)с частотой 13 мгц. Т.е 10 проводов с ацпшки подключены с 10 пинам GPIO, как мне считывать пины с такой частотой? Пните в какую сторону вобще мне посмотреть. Я уже с ног до головы обмазался документациями никак не могу хоть как-то подобраться к этому вопросу. ps. Используя библиотеку pipgio у меня получается запустить апаратный шим до 20Мгц. Но опять же никакого понимания как к этому подвязаться нету.
используя библиотеку wiring pi. Бесконечный цикл while(true) с двумя командами подать 1 на пин, подать 0 на пин, работает с частотой ~470кГц.
Если подытожить: как сделать чтобы while(1) работал с частотой 13мГц ? это задержка 0.074 микросекунды, лол, это вобще возможно?
Я буду вам очень благодарен за любую помощь. Возможно я документацию жопой читаю, т.к мой английский далек от идеала, и есть какое-нибудь решения на готовой библотеке. Может быть вообще нужно делать все как-то по другому.
>>2239802 Я не он, но у тебя по ссылке судя по всему не совсем то что требуется. Данные там же синхронные, они должны приниматься не когда попало, а по переднему или по заднему фронту внешнего (для одноплатника) сигнала.
>>2237003 А в обратную сторону можно? Допустим, указатель на чар я могу кастануть в указатель на uint64_t? >uint8_t arr[8] = {0}; >uint64_t v = ⚙︎(uint64_t⚙︎)arr; ?
Ведь обращение к хардварным адресам/регистрам как-то работает, всякие там ⚙︎(uint32_t⚙︎)addr = data, каст "железного" адреса периферии в структуру с полями её конфига и т.д.?
В чём разница между >#define GPIOA ((GPIO_TypeDef ⚙︎) GPIOA_BASE) Где GPIOA_BASE это просто какое-то число, и >uint32_t addr = &somevar; >some_type⚙︎ var = (some_type⚙︎)addr;
Ведь в обоих случая просто берётся какой-то адрес: либо "из головы", захардкоженный, либо в рантайме считается, беря адрес какой-то другой переменной. Суть одна и та же — взглянуть на область памяти определённым образом.
>>2240470 Ты немного не так понимаешь. Есть шина адресов, есть шина данных. Адрес ты можешь вписывать любую хуйню и если она не прокатит, тебе сразу конпенлятор скажет что ты еблан, потому что в .ldscript вписано максимальный адрес и оно не скомпилируется скорее всего или будет бить уведомлениями. Другое дело, когда тебе производитель, в данном случае STM32 пишет, например, что GPIO это 32 разрядный адрес, это значит что физически к этому адресу есть 32 электронных контакта. Теперь смотрим что будет: Ты ставишь указатель с числом куда сказал производитель(оно не будет превышать максимальное число 32 бит, все окей, если бы было больше 64 бит то приложение на МК ушло бы в ресет или что там прошивка мк говорит) uint64_t gpio = 0xff Теперь ты берешь и пишешь в ячейку памяти с 32 контактами 64 битное число на запись которой нужно 64 контакта gpio = 0xf Что блядь произойдет в конкретной архитектуре конкретного процессора вообще известно только тем кто его сделал. Может два раза перемотать 32 битное число, может процессор послать тебя нахуй и даже не делать такую ебанутую операцию, хуй знает, это undefined behaviour
>>2240479 Как-то не совсем на то ответил, при чём тут запись 64 бит в 32-битную ячейку? Мне ломать ничего не надо, да и я про чтение в основном говорил.
Вот есть там встроенная флеш память. Мне может что-нибудь помешать сделать >const struct mystruct⚙︎ sp = (struct mystruct⚙︎)addr; ? Вроде работает, да и советы такие на стаке были (с оговорками о совместимости из-за пэддингов и выравниваний, разумеется), но я уже ни в чём не уверен.
Ну и касательно >ты имеешь право кастовать указатель на uint64_t только в указатели на войд или чар Вопрос ещё в силе: >А в обратную сторону можно? >uint8_t arr[8] = {0}; >uint64_t v = ⚙︎(uint64_t⚙︎)arr; Работая только с оперативной памятью.
Если я сделаю, скажем, malloc, он найдёт нужное количество байт и вернёт void указатель, который я затем должен кастить в нужный мне тип. Если я создаю переменную в стеке, то он там так же "выделит" память. Почему я не могу её адрес так же в любой (совместимый, так сказать) тип кастить? Я вот этой разницы понять не могу, откуда вообще берётся этот UB из-за type-punning'а. Адрес и адрес, какая разница, откуда он взялся? Если он будет не выровнен как надо, то SIGBUS, да, но я с тем же успехом могу и руками ввести неправильный адрес, при этом компилятор ругаться не будет. В остальном-то что не так? Еидснтвенное, что приходит в голову, это если из-за оптимизаций он вовсе не создаёт никакой переменной, соответственно и адреса как такового нет, хотя что он в таком случае делает с тем, что я как бы эту переменную с числом далее вообще-то использую, не очень понятно.
Возвращаясь к моему изначальному примеру. >uint32_t v = 10; >uint16_t vv = ⚙︎(uint16_t⚙︎)v gcc на ideone выдаёт >warning: dereferencing type-punned pointer will break strict-aliasing rules
Однако, если я сделаю >uint32_t v = 10; >void⚙︎ ptr = (void⚙︎)&v; >uint16_t vv = ⚙︎(uint16_t⚙︎)ptr; То никакого ворнинга о type-punned поинтерах и нарушении strict aliasing'а нет. Но ведь я делаю абсолютно то же самое?!
>>2240470 >А в обратную сторону можно? Можно. Разрешено ровно то, что необходимо. >В чём разница между >#define GPIOA ((GPIO_TypeDef ⚙︎) GPIOA_BASE) В первом случае адрес является константой. Это красный флаг для компилятора, т.к. это может оказаться адресом любого объекта. Во втором случае компилятор понял, что ты берешь адрес somevar и наоптимизировал. Кстати, в uint32 адрес превращать непортабельно, используй intptr_t или хотя бы long.
>>2240508 > откуда вообще берётся этот UB из-за type-punning'а (Тред не читал). UB в стандарте всегда избыточные. Очень сильно избыточные. А причины вот такие, например: - trap representations - это когда процессор конкретную комбинацию бит не любит обрабатывать, и делает эксепшен на нее (этого нигде нет в современных машинах: можно, конечно, заставить x86 на флоатах трапаться, но требуется много телодвижений). - выравнивание - например, нужно, чтобы адрес инта был кратен четырем, и если ты кастанешь чар в инт, это будет соблюдаться не всегда, и будет эксепшен. Понемногу это требование становится ненужным: в x86 это нужно специально включать (по умолчанию все работает без выравнивания, ну кроме SIMD и interlocked), в арм раньше было обязательным, но теперь все тоже работает в любом случае. Нормальные разработчики стандарта сделали бы все это unspecified или даже implementation-defined behavior, но комитет любит портить людям жизнь, поэтому это UB. - третье - это UB-driven оптимизации, когда разработчики стандарта (многие из которых разработчики компиляторов, засевшие в комитете по стандартизации) специально, назло тебе, ради призрачного полпроцента производительности ломают твой код. Например, компилятор может считать, что указатели на int и uint64_t гарантированно ссылаются на разные объекты в памяти (strict aliasing), закладывает на это всякие оптимизации вроде отложенной записи, ты читаешь по неправильному указателю, и читаешь не те данные, что должны были там лежать с точки зрения сишной абстрактной машины.
В целом, если ты знаком с архитектурой и знаешь, что делаешь, все нормально работает и с кастом, и с type-punning через union, диванных не слушай.
#define с многострочными аргументами
fat_alien18/12/21 Суб 19:53:36№2241210449
Возможно ли при использовании макроса в аргументах вставлять несколько строк кода, наподобие следующего примера? #define macroIf(trcod,flcod) if(x<100) { trcod } else { flcod }
int x,y,z;
int main() { macroIf( // 2 строки кода на 1-й аргумент: y = x + z; y = z y; , y = x z; // 1-я строка кода на 2-й аргумент y = y - z; // 2-я строка кода на 2-й аргумент ) } Обратный слэш не нужен в строках 7...13? Комментарии в строках 7...13 можно обозначать двумя слэшами, а не блоком? Если аргументы или комментарии будут содержать внутри запятые, повлияют ли они на подстановку в макросы? Возможно ли макрос подставлять на место аргумента другого макроса?
>>2240876 >в арм раньше было обязательным, но теперь все тоже работает в любом случае. А у того анона STM32, то есть Cortex-M0/M3/M4 и может быть M7. Для M0 выравнивание необходимо. И никуда Cortex-M0 в обозримом будущем не исчезнет, точно так же как 8051.
>>2241366 >>2240876 M4 у меня, и да, выравнивание там всё же нужно, вроде как. По крайней мере я разок с попыткой каста из адреса нечётного элемента чар буфера уже обосрался. При этом, что интересно, ломалось оно только с выключенными оптимизациями (логично), а с -Os он каким-то образом там всё переставлял и у него вполне получалось правильно выполнять код: >uint8_t buf[9]; >receive_data(buf); >uint64_t v = ⚙︎(uint64_t⚙︎)&(buf[1]) Смотреть, что он там сгенерировал как-то не дошли руки.
>>2241382 >M4 у меня, и да, выравнивание там всё же нужно, вроде как. Там не все инструкции могут работать по не выровненным адресам, но большая часть может в отличии от ARMv6 и предыдущих.
>и у него вполне получалось правильно выполнять код: Не слишком ли много лишних действий? Не проще ли было сразу взять uint64_t?
>>2241366 > выравнивание необходимо Да похуй, у компиляторов арм принято в таких случаях просто читать побайтово и собирать. Так что будет перфоманс дроп в качестве UB.
>>2241210 > Возможно ли при использовании макроса в аргументах вставлять несколько строк кода Полноценно нет, на зачем тебе, если в Си переводы строк почти везде можно заменить на пробел?
> Если аргументы или комментарии будут содержать внутри запятые, повлияют ли они на подстановку в макросы? Иногда. Зависит от того, где макрос раскрывается.
> Возможно ли макрос подставлять на место аргумента другого макроса? Да.
>>2241389 Я думаю, что нечётный гарантирует невыравнивание, поэтому так и выразился. А гарантирует, вероятно, нулевой и каждый n-ый. По крайней мере этот код — https://ideone.com/OtuNQX — у меня выдаёт: >&a = 0x2000185f, &b = 0x2000185c, &c = 0x20001858 >&d = 0x20001854, &e = 0x20001850, &f = 0x20001848 >&g = 0x20001840, &h = 0x20001838, &i = 0x20001830 >&j = 0x20001824, &k = 0x20001818 т.е. char где угодно выходит, а все массивы обязательно начинаются на байте, кратном четырём. (На самом идеоне, однако, это не так, и каждый массив начинается на следующем за последним "занятым" байтом.)
>>2241439 >Не слишком ли много лишних действий? Не проще ли было сразу взять uint64_t? Там функция принимает байты извне (по onewire), и затем уже я вот как раз это всё дело и соединяю в один удобный инт для дальнейшей работы (а первый байт в данном случае надо отбросить, потому что там отправленная перед этим команда). Не всегда одно и то же количество байт принимается, не всегда из них все вообще нужны, и т.д. То есть, где-то в любом случае придётся вот так собирать целое число из отдельных байтов.
>>2241580 Не совсем понятно, что тут должно произойти. Типа, выделив под этот юнион 12 байт, нужные для буфера 9 могут оказаться где угодно внутри этого пространства, что ли?
https://ideone.com/0BP8rv до сих пор выдаёт нормальные, кратные четырём адреса: >&un = 0x20001848, &un2 = 0x20001854, u16 = 0x20001806 >&un.buf = 0x20001848, &un2.buf = 0x20001854
Если тут что-то может пойти не так, то и через union type-punning тоже нельзя, но ведь советуют? Говорят, что всё ок и по спеке — https://stackoverflow.com/questions/25664848/unions-and-type-punning А если всё по спеке, то как там может быть не выровнен адрес элементов? Не может же он хранить начало буфера в каком-нибудь 0x1 адресе (из которого обычно uint32_t не прочитать), но когда ты обращаешься к uint32_t элементу, каким-то магическим образом всё же получать правильное значение.
В голове при слове указатель вот такой концепт - память это "массив" байтов (2^64-1) где индекс это номер байта в этом "массиве". указатель это просто индекс (первый) в этом "массиве", а значение это содержимое 'массива' по данному индексу(указателю)
Норм так думать об указателях? или такой концепт в будущем спотыкнется обо что то?
второй вопрос, почему для unsigned чисел реализован механизм операций по модулю, то есть если я выйду за диапазон, оно будет все операции делать по модулю Unsigned_Type_MAX (пример 0u - 1u) Почему для ансайнт чисел такое есть, а для обычных такого нет. И какой в этом глубинный смысл...
>>2242891 >Норм так думать об указателях? или такой концепт в будущем спотыкнется обо что то? Норм. Спотыкнётся об виртуальную память, таблицы страниц, TLB и вот это вот всё.
>>2242891 >или такой концепт в будущем спотыкнется обо что то? Комитет не хочет, чтобы ты так думал. Указатель (в мифическом Эльбрусе) может быть сущностью, для которой оперделны операции создания, преобразования, разыменования, индексации...
>>2242895 > Спотыкнётся об виртуальную память Трансляция адресов никак не пересекается с указателями, а про маппинг в юзермоде можно успешно думать отдельно.
>>2243036 Не только в мифическом эльбрусе, но и в реальном x86 под досом far-указатели - не совсем индексы. Но думать об указателях, как об индексах в адресном пространстве все равно очень удобно и наглядно.
>>2242891 > Почему для ансайнт чисел такое есть, а для обычных такого нет. И какой в этом глубинный смысл... Много-много лет подряд, когда уже весь мир хранил числа в дополнительном коде, комитет по стандартизации сишки отказывался фиксировать метод хранения чисел со знаком. А потом компиляторы подтянулись и начали пилить оптимизации, основанные на UB при переполнении знаковых чисел, и уже ничего не изменить. И вот спустя почти 35 лет после выхода первого стандарта в Си наконец укажут, что у нас дополнительный код, но... UB не уберут.
>>2242895 >>2243036 >>2243045 Благодарю за ответы! В очередной раз убеждаюсь, что если хочешь глубоко понять все эти вещи, то кроме K&R и задач надо читать совместно с учебниками типо: Computer Systems A Programmer’s Perspective
>>2243557 Указатель - это адрес объекта, плюс-минус дополнительные данные у fat pointers. Адрес объекта - это индекс первого байта объекта в адресном пространстве. Он же офсет (смещение) объекта в байтах, считая от начала адресного пространства. На некоторых архитектурах все может быть немного сложнее.
> Что тебе непонятно прямо на пикриле Ты притащил файл, в нем лишь офсеты, указателей и адресов нет по определению, так как нет памяти.
Салаги, записывайте: указатель - это тип данных, значением которого является "адрес". Адрес объекта - это индекс первой ячейки пам'яти, начиная с которой расположен объект.
>>2244250 \e это расширение в некоторых компиляторах. Оно аналогично \033 то есть стрелочка вверх. Косую черту съело потому что по правилам \ начинает esq-sequnce . Чтобы нарисовать косую черту делай так : printf("%c",'\\');
>>2245340 >write не stdout в смысле не stdout? А куда? Я думал stdout это просто какой-то файл и вывод это собственно запись туда. Если нужно отобразить на экран то fflush. Ну а printf делает то же самое только буферизирует и само смывает когда надо.
>>2245348 Насколько я знаю, кэширование stdout производит libc, а запись в файл небуферизируется. Но это надо уточнить и может зависит от реализации. В моей системе по крайней мере так.
>>2245491 Этот прав, я просто не очень точно выразился. Сишный stdout кэширует, а по \n (или по fflush, или если буфер кончится), пишет буфер через write. Там ниже write на уровне ядра тоже может быть кэш, но, по крайней мере, по умолчанию, если у тебя терминал, то все записанное через write сразу отобразится.