Как стать автором
Поиск
Написать публикацию
Обновить
134.51

C *

Типизированный язык программирования

Сначала показывать
Порог рейтинга
Уровень сложности

CURL: почему проект, которому четверть века, не торопится переходить на C99

Время на прочтение4 мин
Количество просмотров16K

Проект curl основан на фундаменте, заложенном в конце 1996 года инструментом под названием httpget.

ANSI C, ставший известным как C89


В 1996 году было не так много хороших альтернатив для создания небольшого и эффективного инструмента командной строки для передачи данных через Интернет. Я не хочу сказать, что C был единственным имевшимся языком, но для меня выбор был прост, и, честно говоря, когда начался этот путь, я даже не думал о каких-то других языках. Мы называли версию этого языка ANSI C, чтобы отличать его от «старорежимного» C K&R. Версию ANSI C позже переименовали в C89 (иногда её называют C90, и это сбивает с толку).

В 2000 году мы выпустили libcurl — библиотеку, предоставляющую всем желающим суперсилы передачи данных через Интернет. Это ещё сильнее оправдывало выбор C. Благодаря C мы могли без проблем предоставить стабильный API/ABI, чего в то время не мог обеспечить даже C++. К тому же это был достаточно портируемый язык, поэтому мы смогли перенести curl и libcurl практически на все современные операционные системы.

Поскольку я хотел, чтобы curl и libcurl предоставляли возможности системного уровня, и нацеливался на максимально широкое распространение, их нельзя было написать ни на одном из высокоуровневых языков наподобие Perl, Python или им подобных. Из-за этого они стали бы слишком большими и тащили за собой слишком много «лишнего багажа».

Я убеждён, что использование (консервативного) C для разработки curl — ключевой фактор его успеха и возможности использования его «где угодно».
Читать дальше →

Как оценить реальную производительность своего кода

Время на прочтение9 мин
Количество просмотров15K

Код, который мы пишем, и который будет исполнен процессором, — две разные вещи. На уровне ассемблера существует миллион вариантов, в каком виде интерпретировать и запустить высокоуровневые команды. Более того, современные компиляторы сильно оптимизируют код, а результат этой оптимизации похож на магию.
Читать дальше →

Пишем Hex Viewer для Flipper Zero

Уровень сложностиСредний
Время на прочтение11 мин
Количество просмотров13K

Примерно месяц назад основная поставка Flipper'ов таки доехала до России. Вопреки моим ожиданиям, это не вызвало волну публикаций про создание приложений под него. Хорошие публикации есть (например, эта и вот эта), но массовости нет. Слишком долго ждали и перегорели? Пишут долго и обстоятельно? Технологический стек устройства не подходит для быстрого и легкого старта? Как бы то ни было, такой расклад ничуть не убавил мотивации поиграться с устройством!! С удовольствием уделил несколько вечеров созданию своего первого приложения под Flipper Zero: Hex Viewer, шестнадцатеричного просмотрщика. О своем опыте и интересных находках расскажу в теле статьи.

Читать далее

Первое знакомство с nRF52832, его оригинальным SDK и средой разработки SEGGER. Мигалка светодиодом Bluetooth

Время на прочтение5 мин
Количество просмотров14K

nRF52832 дешевый и доступный микроконтроллер с поддержкой Bluetooth/

В статье ниже постарался рассказать как сделать BLE UART устройство мигания свтеодиодом.

Читать далее

Ещё раз про умный дом

Время на прочтение11 мин
Количество просмотров11K

Представляю программно-аппаратный проект: локальную сеть умный дом с акцентом на режим охраны. В качестве управляющего устройства используется сотовый телефон с ОС Android версией не ниже 5.0. Через кабель USB телефон подключен к устройству USB/RS485. Для питания всей системы используется блок бесперебойного питания . Узлы управления сбором информации от датчиков и управления исполнительными устройствами реализованы на микросхемах ESP 32. Обмен информацией и питание внешних устройств производится через сетевой кабель. Управляющее устройство (телефон) периодически опрашивает узлы сети и если есть информация от датчиков, в зависимости от настроек, передает сообщения либо в виде SMS, либо в TELEGRAM. А если получена SMS – команда она передается для исполнения на ВУ. Также возможна автономная работа по заложенным сценариям.

Читать далее

Почему массивы начинаются с нуля

Время на прочтение7 мин
Количество просмотров61K
Самое очевидное объяснение: индекс — это смещение относительно начала массива. Так элементы массива легче адресовать в памяти.

Проверим это на C.

#include <stdio.h>
int main()
{
    int data[3] = {1, 2, 3};
    int i = 0;
    printf("Array address: %p\n", data);
    do {
        printf("Array[%u] = %p\n", i, (void *)(&data[i]));
        i++;
    } while(i < 3);
}

Получим результат:

Array address: 0x7ffd7c514a6c
Array[0] = 0x7ffd7c514a6c
Array[1] = 0x7ffd7c514a70
Array[2] = 0x7ffd7c514a74


Как первый (нулевой) элемент, так и сам массив находятся по одному и тому же адресу, поскольку 0-й элемент удалён на 0 элементов от начала. Эта связь между указателями и массивами в C настолько тесная, что их даже можно рассматривать вместе.

Однако это ответ на вопрос «зачем», а не «почему». Нумеровать массивы с нуля стали не сразу. Удивительно, но развитие такого простого вопроса не умещается в предложении или абзаце.
Читать дальше →

Пошаговая GDB отладка ARM процессора из консоли в Win10

Время на прочтение7 мин
Количество просмотров12K

Иногда бывает ситуация когда надо срочно что-то пошагово отладить. При этом нет времени и желания ставить какие-то тяжелые IDE. В таких случаях может помочь пошаговая GDB отладка ARM Cortex M33 из командной строки Windows. В этом тексте я расписал пошаговое руководство того как это сделать.

Читать далее

Почему Нам Нужен UART-Shell? (или Добавьте в Прошивку Гласность)

Уровень сложностиПростой
Время на прочтение17 мин
Количество просмотров16K

Есть такая классическая и одновременно забытая технология отладки FirmWare как интерфейс командной строки поверх UART.

В этом тексте я напишу про достоинства и недостатки отладки через UART Shell.

Читать далее

Сегментная адресация памяти

Время на прочтение7 мин
Количество просмотров10K

Наиболее распространенная модель адресации памяти - плоская, когда у каждого элемента памяти есть глобальный адрес. Но это не единственный способ работы с памятью, в данной статье я хочу рассмотреть одну из альтернатив - сегментную адресаци. Будут расмотрены несколько исторических систем, реализующих этот подход, преимущества сегментной адресации с точки зрения масштабирования и безопастности, а также высказаны гипотезы о причинах, по которым он не прижился (спойлер: буду ругать язык C и операционную систему Unix).

В подавляющем большинстве компьютерных систем для работы с некоторой ячейкой памяти необходимо как-то указать ее адрес, как правило 16-, 32- или 64-разрядное число. Количество бит в адресе часто называют разряностью системы. Часто дополнительно используется механизм "трансляции страниц", который отображает области виртуальной памяти пользовательского приложения в физическую память, которой управляет операционная система. Но в каждый момент времени активна отлько одна "таблица страниц" и с точки зрения приложения (а во многом и с точки зрения ядра ОС) память остается плоской.

Рассмотрим старый процессор Intel 86/88/186. Размер регистров этих процессоров всего 16 бит, что позволяет адресовать всего 64 килобайта памяти. Когда эти микросхемы разрабатывались, такого размера памяти уже не хватало для многих приложений, а 32-разрядные процессора были слишком дороги. Проблему решили добавив в архитекруту сегментные регистры. При обращении к памяти к 16-битному адресу (хранящемуся в реристре общего назначения или прямо в коде команды) прибавлялось значение сегментного регистра, сдвинутое на 4 бита (что тоже самое, умноженное на 16) и полученное значение использовалось как физический адрес. Такой подход позволял адресовать до одного гигабайта памяти. В архитектуре персональных компьтерах IBM PC, созданных на базе этих процессров, часть адресного пространства было зарезервировано для системных нужд, а пользовательским приложениям и ОС было доступно до 640 килобайт. Но не все так просто.

Читать далее

Как завладеть сетью /16 с помощью libpcap и libdnet

Время на прочтение16 мин
Количество просмотров14K

Всем привет. Сегодня я попытаюсь рассказать про сетевое программирование на довольно низком уровне, с библиотеками libpacp и libdnet. Про последнюю многие наверное и не слышали, т.к. информации о ней в сети фактически нет. А ведь её использует сам Fyodor :)
Читать дальше →

Rust должен умереть, МГУ сделал замеры

Время на прочтение25 мин
Количество просмотров107K

В предыдущих сериях:



Медленно, но верно Раст проникает не только в умы сотрудников больших корпораций, но и в умы школьников и студентов. В этот раз мы поговорим о статье от студента МГУ: https://rustmustdie.com/.


Её репостнул Андрей Викторович Столяров, доцент кафедры алгоритмических языков факультета ВМК МГУ им. М. В. Ломоносова и по совместительству научрук студента-автора статьи.


Я бы сказал, что тут дело даже не в том, что он "неинтуитивный". Дело скорее в том, что компилятор раста сам решает, когда владение "должно" (с его, компилятора, точки зрения) перейти от одного игрока к другому. А решать это вообще-то должен программист, а не компилятор. Ну и начинается пляска вида "как заставить тупой компайлер сделать то, чего я хочу".
Бред это всё.

— А. В. Столяров
Кощунство!

Что Должно Быть в Каждом FirmWare Pепозитории

Время на прочтение10 мин
Количество просмотров8.1K

В этом тексте я предлагаю порассуждать, что же должно быть в нормальном взрослом firmware репозитории безотносительно к конкретному проекту.

То есть перечислить самые универсальные и переносимые программные компоненты (кирпичики), которые могут пригодиться в практически любой сборке.

Читать далее

Фокусы оптимизации размера исполняемых файлов ELF. Поддержка 4 ОС в 400 байт единственного бинарника

Время на прочтение29 мин
Количество просмотров7.2K

В этом посте я расскажу о некоторых уловках, которыми я воспользовалась, чтобы уменьшить двоичные файлы С/С++/Python с помощью ассемблера для x86. Здесь всё крутится вокруг кодовой базы Cosmopolitan. Дело в том, что из недавнего отзыва по проекту ELKS я узнала, что мой код там всем понравился и они хотят узнать больше о том, что трюки cosmo могут дать проектам вроде «Linux-порта i8086». Я почувствовала, что мы с ребятами проекта ELKS «одной крови», ведь первое, что я написала при создании Cosmopolitan, — это загрузчик i8086, который назывался Actually Portable Executable. А ещё мне было приятно узнать, что людям, которые погрузились в эту проблему гораздо раньше меня, нравятся мои наработки в Cosmopolitan. И тогда я решила, что неплохо было бы поделиться ими с более широкой аудиторией.


[Shinmyoumaru Sukuna]

Читать дальше →

Ближайшие события

Как я портирую код с помощью Hebron

Время на прочтение3 мин
Количество просмотров4K

В своей предыдущей статье я упомянул Hebron - утилиту для портирования кода с C на C# или на Rust.

В этой статье хотелось бы подробно расписать - как я с ней работаю.

Написанное можно воспринимать как своего рода мануал на тот случай, если кто-нибудь тоже захочет что-нибудь портануть.

Итак, портирование осуществляется в 4 шага:

Читать далее

StbSharp: история ненужного проекта

Время на прочтение6 мин
Количество просмотров7.1K

В этой статье я бы хотел рассказать о своем хобби проекте под названием StbSharp.

Итак, в 2016 году мне пришла в голову весьма банальная идея - сделать собственный игровой кросс-платформенный движок на C#. И я озаботился поиском кросс-платформенной же библиотеки для загрузки картинок. Внезапно выяснилось, что подходящей просто не существовало. Было множество платформо-зависимых решений(напр. System.Drawing). А так же имелась SixLabors.ImageSharp. Но она была в состоянии ранней альфы. Мне же хотелось работать с решением, проверенным временем. Так я пришёл к идее портировать stb_image.h (очень популярной в геймдеве single-header библиотеки для загрузки картинок) на C#.

"А разве не легче было написать биндинги для нативной библиотеки? Хоть для той же stb_image?",- задаст справедливый вопрос читатель. Да, легче. И правильнее. О чём, собственно, и говорит заголовок этой статьи. Конечно, использование биндингов доставляет некоторые неудобства в плане того, что необходимо доставить соответствующий нативный бинарник на устройство конечного пользователя. Однако эти неудобства с лихвой окупаются достоинствами. А именно лучшим перформансом и портируемостью.

Однако, проект показался мне столь интересным, что я проигнорировал эти справедливые возражения.

Читать далее

Написание расширений PostgreSQL на языке С — это интересно

Время на прочтение6 мин
Количество просмотров5.6K

PostgreSQL — это мощная система управления реляционными базами данных с открытым исходным кодом. Она дополняет язык SQL новыми фичами. СУБД определяется не только ее производительностью и встроенными фичами, но и способностью поддерживать персонализированную/дополнительную, специфичную для пользователя функциональность. Некоторые из этих возможностей могут быть представлены в виде конструкций или модулей базы данных, таких как хранимые процедуры или функции, но их объем обычно ограничен функциональностью, предоставляемой СУБД. Например, как вы напишете кастомное приложение для анализа запросов, которое будет находиться внутри вашей СУБД?

Читать далее

Как не быть программистом, раскурить eBPF за сутки и начать мониторить DNS

Время на прочтение22 мин
Количество просмотров11K

Представим: сервер может отправлять легитимные запросы, но IP, на которые он будет их слать, неизвестны. В журнале сетевого фильтра видно что запросы таки да, идут. Но не ясно - это как раз легитимные или информация уже утекает к злоумышленникам? Было бы проще если бы был известен домен на который сервер посылает данные. Увы, но PTR не в моде, а securitytrails показывает или ничего, или слишком много по этому IP.

Можно запустить tcpdump. Но кто захочет постоянно смотреть в монитор? А если сервер не один? Есть packetbeat. Это чудовище, которое выжрало процессор на всех серверах. Брр… Не хочу о нём вспоминать. Osquery - неплохой инструмент который многое знает о сетевых подключениях и ничего - о DNS-запросах. Соответствующее предложение было просто закрыто. Zeek - о нём я узнал когда начал искать как отслеживать DNS-запросы. Похоже он неплох, но меня смутило два момента: он следит не только за DNS, а значит ресурсы будут тратиться на работу результат которой мне не нужен (хотя, возможно, в настройках можно выбрать протоколы); а ещё он ничего не знает о том какой процесс послал запрос.

Неужели это всё? Я вроде бы что-то слышал про eBPF…

Читать далее

Приёмы высокоуровневой векторизации на примере Card Raytracer

Время на прочтение20 мин
Количество просмотров3.8K

Хочу рассказать о том, как занимался оптимизацией card raytracer - минимального рейтрейсера, код которого умещается на визитке.

Точнее, это развёрнутая для лучшей читабельности версия, которая в форумной ветке
использовалась как тест скорости разных языков.

Когда я наткнулся на эту ветку, я как раз изучал компиляторы Cи, и конечно немедленно вознамерился всех порвать обогнать. В результате действительно обогнал, но с нарушением правил - слегка поправив структуру данных.

Тем не менее, это хороший пример того, как можно "заточить" код под векторизацию, с сохранением читабельности и умеренным ростом объёма и сложности. Я расскажу, какие есть варианты векторизации, как перестроить код и данные, и наконец, как переложить на компилятор черновую работу по кодогенерации - используется автовекторизация, векторные расширения и совсем немного интринсики.

Наверное, статья в большей степени полезна новичкам, но и опытные разработчики (по привычке с 2000-го года пишущие SIMD-код интринсиками) могут найти что-то новое.

Компилятор - в основном Clang, можно GCC, в конечном итоге я адаптировал и под MSVC.

Читать далее

Руководство по CMake для разработчиков C++ библиотек

Время на прочтение18 мин
Количество просмотров110K

Данное руководство позволит читателю составить полную картину того, как организовать сборку C++ библиотек с использованием современных возможностей CMake. Предполагается, что читатель имеет представление о базовых понятиях из мира CMake и динамических/статических C++ библиотек, так как в руководстве они могут не объясняться.

Читать далее

Разбираемся с EXCEPTION_CONTINUE_EXECUTION

Время на прочтение6 мин
Количество просмотров3.3K

Механизм структурированной обработки исключений (Structured Exception Handling, SEH) позволяет не только "отловить" сгенерированное исключение, но и вернуться к инструкции, вызвавшей сбой и попробовать выполнить ее заново.

В данной статье разбирается использование механизма SEH для возврата к инструкции, вызвавшей исключение.

Читать далее

Вклад авторов