Dmitry Develop
176 subscribers
77 photos
35 videos
88 files
205 links
Этот канал в основном будет интересен новичкам в программировании и людям немного поопытнее.
Здесь я буду делиться своими новостями и достижениями в программировании.

Разработка, программирование; c++, gcc, g++, gnu, mingw; winapi, windows; vscode.
Download Telegram
Рубрика "полезные флаги для GCC (mingw)".

Я часто нахожу полезные флаги компилятора, которые облегчают исправление кода, но забываю рассказать о них другим).

Сегодня вопрос в чате напомнил мне о ситуации, когда случайно или по незнанию в функцию printf передаётся аргумент, который не соответствует квалификатору или наоборот.
Например, функция ожидает signed int, но получает unsigned int.

-Wformat
предупреждает о несоответствии типов аргументов и квалификаторов

-Wformat-signedness
если указан предыдущий флаг, предупреждает о несоответствии знаковости квалификатора и аргумента.

Эти флаги доступны с версии GCC 5.0 и выше.

ссылка на канал | ссылка на группу
👍21
Использование define'ов, конечно, осуждаемо и часто сомнительно, но в условиях, когда работы много, а времени мало, выбирать не приходится.
Тем более, разве, define'ы не помогают избавиться от повторения кода?
Получилось сделать довольно быстро и удобно.

Примерно таким образом я вижу свою будущую переработанную строковую библиотеку для работы с кодировками utf-8 и utf-16: просто берёшь и получаешь желаемый результат.

ссылка на канал | ссылка на группу
👍1
При запуске отладки по нажатию на F5 иногда в консоли появляется ошибка и отладка не запускается.
Бывает, даже повторяется несколько раз подряд.
Обновление vscode и gcc до последних версий не помогло.
Намеренно повторить это не получается.

Кто сталкивался с таким поведением отладки в vscode с расширением C++ от microsoft?

ссылка на канал | ссылка на группу
IDECompilers.png
521.7 KB
ссылка на канал | ссылка на группу
Dmitry Develop
IDECompilers.png
Меня всегда забавляет читать "труды" людей на тему, в которой они абсолютно не разбираются.

Заголовок прямо кричит: ищете самые лучше C++ компиляторы? Узнайте о ТОП 6-и, которые вы обязаны попробовать.
То есть статья должна быть именно на тему компиляторы С++ и должна помочь выбрать какой-то конкретный из них или дать исчерпывающие ответы и объяснения.

Во вступлении говорится о каком-то чувстве "студента, программиста или человека в IT, который постоянно меняет компиляторы".
Уже немного странно, но ладно, это ведь только вступление, хотя и такое безобразное и не затрагивающую обширную тему напрямую.

И тут внезапно заголовок "Что такое IDE".
Ладно, допустим, это действительно важно рассказать о существовании и что это вообще такое этот ваш IDE.
Не буду затрагивать определение от автора что такое IDE, оно более-менее отвечает на вопрос заголовка для обывателя.
Но причём тут "каждый WEB разработчик знает..." и C++ компилятор?

И тут автор наконец-то переходит к сути статьи, перечислению тех самых лучших компиляторов по мнению не пойми кого:
"Разве мы же хотим самого лучшего? Поэтому вот некоторые самые лучше компиляторы C++, которые вы можете найти в 2022 году".

"1. Visual Studio Code FREE"
И начинает перечислять IDE, редакторы кода и notepad++ и кратко описывать их.🤨
Я хотел видеть компиляторы C++, какие существуют, в чем заключаются их отличия, преимущества и недостатки, может, краткую историческую сводку, но не это всё.

Сама статья:
https://in.godaddy.com/blog/looking-for-the-best-c-compilers-check-out-top-6-you-must-try/

ссылка на канал | ссылка на группу
Полезные ссылки для С++ разработчиков.

Когда пишут привет, но не переходят к сути вопроса сразу:
https://nohello.net/
https://neprivet.com/

Когда задают вопрос, подразумевающий другие вопросы, вместо конкретики:
https://nometa.xyz/

Когда спрашивают какие-то очевидные темы, и так хочется послать в google:
https://googlethatforyou.com/

Когда просят решение проблемы Y вместо проблемы X:
https://ru.wikipedia.org/wiki/Проблема_XY_(Ошибка_молотка)

Как правильно задавать вопросы:
http://citforum.ru/howto/smart-questions-ru.shtml
https://www.google.com/search?q=как+задавать+вопросы

MRE (minimal reproducible example):
https://stackoverflow.com/help/minimal-reproducible-example
https://en.wikipedia.org/wiki/Minimal_reproducible_example

Список различных IT групп:
https://t.me/it_chats/865

Справочник по C++:
https://en.cppreference.com/w/

Черновик стандарта C++:
https://eel.is/c++draft/

Квест на знание стандарта C++:
https://cppquiz.org/

Дорожная карта C++:
https://roadmap.sh/cpp

Различная информация по С++:
https://github.com/JoshuaJakowlew/cppfaq
https://gist.github.com/honey-speaks-tech/225e0ce05430a6c2e3d3c68e0e4a35d9

Неявное становится явным:
https://cppinsights.io/

Перевод непонятных Си объявлений на понятный английский язык:
https://cdecl.org/
https://github.com/paul-j-lucas/cdecl

Преобразование msvc/gcc mangled символов в читаемый вид:
https://demangler.com/

Что такое UB в С++:
https://github.com/Nekrolm/ubbook/blob/master/README.md

Советы по стилю написания C++ кода:
https://isocpp.github.io/CppCoreGuidelines/CppCoreGuidelines

Изучение языка C++:
https://www.learncpp.com/ (оригинал на английском)
https://ravesli.com/uroki-cpp/ (перевод на русский)
https://acode.com.ua/uroki-po-cpp/ (перевод на украинский)

Online компиляторы:
https://www.onlinegdb.com/online_c++_compiler
https://godbolt.org/

Выравнивание, отступы и упаковка членов данных структуры:
https://www.geeksforgeeks.org/structure-member-alignment-padding-and-data-packing/
https://habr.com/ru/articles/142662/
https://learn.microsoft.com/ru-ru/cpp/cpp/alignment-cpp-declarations

Что такое trap representation?
https://ru.stackoverflow.com/a/838699

Unicode таблица символов:
https://design215.com/toolbox/utf8-4byte-characters.php

Изучение системы контроля версий git:
https://git-scm.com/book/ru/v2

Изучение git в виде интерактивной игры:
https://learngitbranching.js.org/

Преобразование кодировок:
https://2cyr.com/decode/
https://dencode.com/

Различные операции над кодировками:
https://onlinetools.com/utf8/convert-utf8-to-binary

Различная информация по unicode:
https://utf8everywhere.org/

Поиск по репозиториям github:
https://grep.app/

Конфигуратор стиля форматирования кода:
https://zed0.co.uk/clang-format-configurator/

Какие проекты написать новичку:
https://github.com/siliciusQ/Programming-challenges-v4.0

Почему отправлять код в виде фотографии плохо:
https://idownvotedbecau.se/imageofcode

ссылка на канал | ссылка на группу
2🫡1
image_2023-10-31_19-27-48.png
46.2 KB
ссылка на канал | ссылка на группу
image_2023-10-31_19-27-48.png
165.5 KB
ссылка на канал | ссылка на группу
Dmitry Develop
image_2023-10-31_19-27-48.png
Сегодня весь день разбираюсь с диапазонами и моей реализацией полосы прокрутки.

В решении проблемы я зашёл в тупик, поэтому я решил рассмотреть всю теорию с самого начала.
Этот подход уже принёс свои результаты: был найден участок кода, который будет давать правильный размер ползунка только в диапазоне [0, N] или [N, 0].

Я думал, что rangeMap сможет решить все практические случаи.
Но оказалось, что пытаться все вычисления подвести к диапазонам даёт не всегда более простой или эффективный код.
Придётся пересмотреть алгоритм работы и / или написать функцию, которая будет нормализовать или приводить число в нужный диапазон.

Также по этому случаю решил немного отрефакторить функцию rangeMap.
Спасибо всем, кто давал мне советы, как можно сделать лучше.
Но я всё равно сделал немного по-своему).

ссылка на канал | ссылка на группу
👍1🔥1
Циклические зависимости и зависимость от порядка перечисления библиотек в GCC.

Бывало ли у вас такое, когда вы точно указали все нужные библиотеки, но линковщик всё равно выдаёт ошибку "undefined reference to..."?
Или от изменения порядка перечисления библиотек, ошибка меняется или одна пропадает и появляется другая?

Это происходит из-за того, как работает линковщик gnu и требует стандарт POSIX.
Линковщик ищет определение упоминаемых символов в указанных библиотеках слева направо и всего один раз, забывая о библиотеке после разрешения символов.

Когда библиотека first зависит от second, a second зависит от first, можно при помощи комбинаторики и сочетания перебрать все их комбинации: 2! = 2.
-lfirst -lsecond -lsecond -lfirst

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

Чтобы решить эту проблему, используйте одну из конструкций, которые укажут линковщику искать определение символа рекурсивно по списку до тех пор, пока все упоминаемые символы не будут разрешены:
-Wl,--start-group -lfirst -lsecond -Wl,--end-group
-Wl,-( -lfirst -lsecond -Wl,-)


Как использовать эти ключи в CMake:
https://stackoverflow.com/a/73641444

ссылка на канал | ссылка на группу
👍3
trailingWhitespace.png
58.7 KB
ссылка на канал | ссылка на группу
Dmitry Develop
trailingWhitespace.png
Бывало у вас такое, что, после редактирования, рефакторинга или копирования кода, у вас появлялись раздражающие пробелы или табуляция в конце строки (trailing whitespace)?

Кто страдает перфекционизмом или просто хочет поддерживать чистоту в коде, при помощи замены и регулярного выражения [ \t]+$ можно решить эту проблему.

В visual studio code (vscode) также можно нажать сочетание клавиш ctrl + shift + P, написать и выполнить команду "Trim Trailing Whitespace".
Или включить выполнение этой команды при сохранении файла в настройках по названию Files: Trim Trailing Whitespace.

ссылка на канал | ссылка на группу
👍1
image_2023-11-10_09-53-28.png
72.2 KB
ссылка на канал | ссылка на группу
Dmitry Develop
image_2023-11-10_09-53-28.png
Увеличил глубину и частоту дискретизации передачи сигнала с микроконтроллера на ПК с 8 до 16 bit и с 500 до 5000 Hz.

Было как-то неприятно увеличивать количество передаваемых байт с 4 до 8, но производительности микроконтроллера, ПК и моего кода хватило.
И я до последнего был уверен, что всё сломается, появится трудноуловимый баг или вообще ошибка сегментации, когда я перепишу код обработки данных на новый протокол общения.

Ну а ещё я постепенно чиню полосу прокрутки.
Сейчас уже правильно вычисляется размер ползунка, ничего не ломается, если указать диапазон [0, -N], и правильно вычисляется даже отрицательный отступ.

ссылка на канал | ссылка на группу
IMG_20231121_161136.jpg
3.3 MB
ссылка на канал | ссылка на группу
1
Dmitry Develop
IMG_20231121_161136.jpg
Наконец-то приехала небольшая поддержка от спонсора нашего общего проекта).

ссылка на канал | ссылка на группу
ссылка на канал | ссылка на группу
Dmitry Develop
ссылка на канал | ссылка на группу
Сегодня я открыл для себя новый инструмент, который делает сгенерированный компилятором ассемблерный код более читаемым.

Если вы когда-нибудь смотрели преобразованный С++ код в ассемблерный код или видели сообщение об ошибке "undefined reference to _Z7timeNowPx", вы могли заметить, что привычное название функции, например, timeNow(uint64*) превращается в _Z7timeNowPx.

И чем длиннее название символа, больше количество аргументов и сложнее принимаемые и возвращаемый типы данных, тем страшнее и непонятнее будет итоговое название.

Этот механизм называется name mangling.
Он нужен для того, чтобы компоновщик (linker) мог различать символы с одинаковыми названиями, перегрузки функций и не только, создавая для каждого символа уникальное неповторяющееся название.

Чтобы преобразовать mangled символы в читаемый вид, нужна программа c++filt.exe, которая поставляется вместе с компилятором gcc.
При запуске программа будет ожидать текст в потоке ввода и выводить в консоль преобразованный текст.
Так как она не умеет работать с файлами напрямую, нужно перенаправить поток ввода и вывода:
c++filt.exe < mangled.asm > demangled.asm

Это работает так:
Запускается программа c++filt.exe, в поток ввода передаётся содержимое файла mangled.asm и потом вывод программы перенаправляется в файл demangled.asm.

Предыдущую конструкцию вообще можно объединить в одну строчку с генерацией ассемблерного кода:
g++.exe -S -masm=intel -fverbose-asm -o mangled.asm main.cpp && c++filt.exe < mangled.asm > demangled.asm

Как объединить несколько команд и перенаправить ввод-вывод в вашем терминале и операционной системе ищите самостоятельно:
"chain commands in terminal"
"terminal redirect input output"

Более сложный пример:
_ZNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEE15_M_replace_coldEPcyPKcyy

std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::_M_replace_cold(char*, unsigned long long, char const*, unsigned long long, unsigned long long)

ссылка на канал | ссылка на группу
🔥2🤯1
Раньше здесь был ъуъ).

...
Недавно я делал лабораторную работу, в которой надо было в runtime создавать одно- и многомерные массивы (1D, 2D, 3D) большого размера, заполнять их: последовательными значениями по возрастанию, по убыванию и перемешанными значениями (shuffle), а потом применять к ним различные алгоритмы сортировки.

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

Способов передачи массивов в функцию довольно много: от написания шаблонной функции до передачи типа int (*row)[10].
У каждого способа были свои преимущества и недостатки: один был сложным, второй подходил только для массивов фиксированного размера, третий вообще активно использовал UB (но я не уверен).

Потом я вспомнил, что в Си / С++ массивы в памяти хранятся построчно (row-major order):
// многомерный массив
int array[3][2][3]
{
{
{
{ 1, 2, 3 }
},
{
{ 4, 5, 6 }
}
},
{
{
{ 7, 8, 9 }
},
{
{ 10, 11, 12 }
}
}
{
{
{ 13, 14, 15 }
},
{
{ 16, 17, 18 }
}
},
};
// представление в памяти
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18


Многомерный массив привести к одномерному и соответственно вычислить индекс:
// было:
array[k][j][i]
// стало:
array[k*Y*X + j*X + i]


Поэтому я решил, что массив от 1 до 3 измерений (можно и больше), я буду выделять так:
// было:
new int[z][y][x] { };
// стало:
new int[z * y * x] { };


Заметьте, что, в привычном виде для разработчиков игр и графики, оси вектора (размерности) перечисляются в таком порядке: x, y, z.
А единичные векторы, из суммы которых можно представить любой вектор, в таком: i, j, k.
Но в C++ размерности надо указывать задом наперёд.

В итоге, чтобы передать такой flatten массив в функцию достаточно будет:
void arrayModify(int* array, const int x, const int y = 1, const int z = 1);


Можно было создавать не двумерный массив, а массив указателей на одномерные массивы.
Но это сложнее: надо создавать сначала массив указателей, потом через цикл создавать массив строк и удалять соответственно в обратном порядке.
Такой массив можно передавать в функцию, как int** array.
Но как дело доходит до трёхмерного... оно того не стоит.
Да и универсальный алгоритм сложнее написать, если вовсе невозможно.

ссылка на канал | ссылка на группу
👍3🕊1
Я заметил, что в последнее время я в основном пишу всё в группу, но не в канал.

Хотя канал был создан, чтобы делиться с другими чем-то по тематике около С++, электроники и техники.
Ну, а ещё чтобы не доставать своих друзей и близких часовыми лекциями по поводу языка С++ и моих проектов)).

Думаю, причина в том, что я слишком сильно завысил критерии к качеству и к тематике поста.
А ещё как-то не хочется по каждому пустяку делать пост в канале.

Что думаете, я из пустяка сделал себе проблему?
И стоит просто забить и выкладывать почти всё в канал после вычитки и всех правок?

ссылка на канал | ссылка на группу