C++23: проверка на присутствие поля структуры
Небольшой мемориз. Пока не дошло до мышечной памяти.
Естественно - через концепты.
Hatred's Log Place
Небольшой мемориз. Пока не дошло до мышечной памяти.
Естественно - через концепты.
Всё не получается найти время написать про все выходы после возврата с Киргизии: то времени нет, то “вдохновения”, то ещё чего. Хотя иногда интересные моменты проглядывают. Поэтому решил описать всё одной заметкой, кратенько.
Итак…
Киригизия началась для меня относительно спонтанно. Это если смотреть на то, как готовились к другим походам, когда билеты покупались уже в январе, а вся основная канва была ясна и понятна к концу осени предыдущего года.
Тут же март месяц, в группе «ПВД анонсы» сообщение от Вовы с которым единожды ходил на г.Мечта под руководством Зелёного осенью прошлого (2024) года… Мысли начали делать жуууууу в голове. Робко уточняю количество мест (планируется передвижение на авто, поэтому число участников ограничено 4 персонами), но оказывается, что желающих пока только два: собственно Вова и Даша. С Дашей тоже ходили только Мечту и (склероз хорошая болезнь: каждый день новости), как оказалось позже, встречали вместе 2024 НГ на Фалазе с GT.
Но желание куда-то, особенно в новый район, выбраться на фоне тотального оскуднения собственной фантазии, всё же взяло верх. Решаюсь и вписываюсь.
Просто заметка, что бы самому потом не потерять.
Руководство для отладки потоков в RTOS NuttX:
Отмечу, что последние версии GDB и OpenOCD включают весь необходимый софт для работы. А если грузить ELF как-то так:
arm-none-eabi-gdb main.elf \
-ex "target extended-remote | openocd -f interface/stlink.cfg -f ${OPENOCD_CFG} -c 'gdb_port pipe' -c '\$_CHIPNAME.cpu0 configure -rtos nuttx'" -x openocd_nuttx_gdb.rc
То содержимое openocd_nuttx_gdb.rc стоит сделать таким:
define hookpost-file
eval "monitor nuttx.pid_offset %d", &((struct tcb_s *)(0))->pid
eval "monitor nuttx.xcpreg_offset %d", &((struct tcb_s *)(0))->xcp.regs
eval "monitor nuttx.state_offset %d", &((struct tcb_s *)(0))->task_state
eval "monitor nuttx.name_offset %d", &((struct tcb_s *)(0))->name
eval "monitor nuttx.name_size %d", sizeof(((struct tcb_s *)(0))->name)
end
eval "monitor nuttx.pid_offset %d", &((struct tcb_s *)(0))->pid
eval "monitor nuttx.xcpreg_offset %d", &((struct tcb_s *)(0))->xcp.regs
eval "monitor nuttx.state_offset %d", &((struct tcb_s *)(0))->task_state
eval "monitor nuttx.name_offset %d", &((struct tcb_s *)(0))->name
eval "monitor nuttx.name_size %d", sizeof(((struct tcb_s *)(0))->name)
т.е. что бы и хуком на команду file сработало и сразу же отработало. Как будет более красивое решение - подправлю.
Ещё остался не опробованным вариант отладки с включенной PROCFS и скриптом nuttx/tools/pynuttx/gdbinit.py из поставки NuttX.
Две очень хорошие статьи, что бы расставить точки над i:
Тезисно:
Дополнительно:
Проблема: после вывода ноутбука в сон и последующего пробуждения FFmpeg выдаёт примерно следующее:
[AVHWDeviceContext @ 0x55ec837f1800] cu->cuInit(0) failed -> CUDA_ERROR_UNKNOWN: unknown error Device creation failed: -1313558101.
Команда у меня такая:
ffmpeg -vsync 0 -hwaccel cuda -hwaccel_output_format cuda -i INPUT.mkv -c:a mp3 -c:v h264_nvenc -profile baseline -y OUTPUT.mkv
С аналогичной ошибкой отваливается и Kdenlive при попытке использовать аппаратный кодек.
Как оказалось, ошибка известная ( и на форуме nVidia), там же можно найти WA:
This bug disappears after running nvidia-bug-report.sh for some reason, CUDA works again after running nvidia-bug-report.sh.
Edit: After more research I found out that running nvidia-settings as root somehow fixes the problem.
Edit 2: Loading the nvidia-uvm module thoughmodprobe nvidia-uvmfixes this issue
WA:
sudo modprobe -r nvidia_uvm
sudo modprobe nvidia_uvm
Я засунул эти команды в suspend-hook Systemd:
sudo systemctl edit --force --full nvidia-uvm-wa-sleep.service
Содержимое:
[Unit]
Description=nVidia UVM suspend bug WA
Before=sleep.target
StopWhenUnneeded=yes
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart= modprobe -r nvidia_uvm
ExecStop= modprobe nvidia_uvm
[Install]
WantedBy=sleep.target
Включить:
sudo systemctl enable nvidia-uvm-wa-sleep.service
Содержимое юнита по мотивам:
Самостоятельное осмысление навеянное https://t.me/grokaemcpp/627.
Не задумывался над сценариями использования, хотя они есть с C++11.
Раньше была возможность использовать квалификатор const:
struct Foo {
void method(); // (1)
void method() const; // (2)
};
Тут вроде логично, когда какой метод будет вызван.
C++11 добавил возможность пометить метод квалификатором ссылочности: ref-qualified:
&const&&&const&& - хотят это сценарий очень странный.Первое, что нужно отметить, что если хотя бы один из них определён, то он кофликтует с (1) и (2). Т.е. у вас или ref-qualified или non-ref-qualified:
struct Foo {
#if 0
void method(); // (1)
void method() const; // (2)
#else
void method() &; // (3)
void method() const&; // (4)
void method() &&; // (5)
void method() const&&; // (6)
#endif
};
Второе: что и когда вызывается (или - ниже обозначает, два случая, для сравнения: когда использует и когда не используется ref-квалификация ):
Foo foo;
foo.method(); // (а) вызовется или (1) или (3), либо ОШИБКА, если перегрузка не указана
const Foo const_foo;
const_foo.method() // (б) вызовется или (2) или (4), либо ОШИБКА, если перегрузка не указана
Foo{}.method(); // (в) вызовется или (1) или (5), либо (4), если перегрузка не указана
(const Foo){}.method(); // (г) вызовется или (2) или (6), либо (4), если перегрузка не указана
Тут логика такая: есть имя - вызовется &, нет имени - вызовется &&. И стоит внимательно посмотреть кейсы (в) и (г) для “старого” поведения и нового, но когда перегрузка по && не указана.
Третье: перегрузки могут быть помечены delete: удалённые функции тоже используются в поиске перегрузок и, если наиболее подходящая перегрузка удалена - будет ошибка компиляции.
Ну и для чего может быть нужно: оптимизации и защита. К примеру, если мы вызвали && метод, то мы точно знаем, что мы - временный объект. поэтому, мы можем сделать не просто возврат чего-то, а сделать этому std::move(), пометить метод delete и запретить вызваться или вернуть копию, а не ссылку или указатель.
Другой пример: висячие ссылки или другие отсылки к уничтоженным ресурсам.
struct Bar {
std::string _val;
#if 0
std::string_view get() const { return _val; } // (7)
#else
std::string_view get() const& { return _val; } // (8)
std::string get() && { return _val; } // (9) - можно и std::move(_val), но зависит от
endif
};
Тут вместо std::string_view может быть const std::string&, но со string_view можно проще отловить ситуацию с доступом к уничтоженному объекту:
// как помощиник
Bar request() {
return Bar{};
}
...
auto sv = request().get(); // (д)
some_function(sv); // (е)
Здесь без ref-qualified методов в (д) будет вызван (7), что приведёт в (е) и дальше по коду к обращению к уничтоженному объекту Bar::_val.
При использовании перегрузок по ref-qualified, будет вызван (9) и мы вернём копию строки (или более оптимально, если через std::move(_val)).
Отсюда, имхо, основное применение: если возвращаем некий референс (ссылку, view/span) на внутреннюю структуру класса, то имеет смысл использовать указание ссылочных квалификаторов, причём обоих: & и && - второй будет уточнять поведение для временного объекта. Если уточнения по поведение не нужно, то использование ссылочных квалификаторов избыточно (но смотреть кейсы кейсы (в) и (г)) .
На правах мемориза.
LocalSend ( официальный сайт) - удобный инструмент для обмена файлами между устройствами в локальной сети без подготовленной инфраструктуры. Что примечательно - open source.
Мне потребовалось что бы быстро перекидывать файлы между несколькими андроидами и ноутбуком на Linux. Для своих персональных устройств я использую давно KDE Connect, но привязывать “левые” устройства и потом каждый раз отвязывать - не добно. А вот LocalSend решает.
Для полноты картины, обсуждение на 4PDA:
На андроид можно поставить их Google Play, F-Droid и ручками APK. На Manjaro - есть в AUR.
Просто заметка по версиям.
В AnyDesk есть возможность туннелирования TCP. Да, вот прям как в SSH. Очень удобно для использования в “чужом” или неподготовленном окружении. Использовал, например, для удалённой отладки кода на устройствах очень сильно далеко от меня (вплоть до другого континента)
Доступна в бесплатной версии, но с нюансом:
При этом версия 6.2.1 пока работает. FYI.
Ну и сразу. Есть RustDesk. Возможности форвардинга есть. Плюс можно свой сервер разворачивать. В реальных условиях пока не проверял.
Не стартует удалённая отладка. Причём без какого-то фидбека.
Если включить логи:
export QT_LOGGING_RULES='*=true;qt.*=false;qtc.*=true;qtc.clang*=true'
и запустить сессию QtC, то при запуске отладки можно увидеть что-то вроде:
qtc.utils.process: Process 162 starting (non blocking, main thread): --multi :10000
qtc.utils.process: Process 162 finished: result=3, ex=255, 0 bytes stdout: "", 0 bytes stderr: "", 0 ms elapsed
Суть проблемы в том, что на удалённой стороне просто не установлен gdbserver. Соответственно нужно его установить и всё починится.
Как минимум на версии 16.x проблема присутствует. Как и на 17.0.0-beta1 (16.0.82). Проблема определена в переписке.
Веб-сервисы вещь хорошая и удобная… Пока их не блокируют. Поэтому предпочитаю для своих домашний поделок использовать KiCAD. Естественно, что не всегда хватает какого-то символа, посадочного места или 3D вида компонента. При этом в той же EasyEDA есть куча оных уже в готовом виде. Если не вдаваться в подробности соответствия каким-то стандартам, то было бы неплохо, стащить оную и использовать у себя.
Первым тулом, которым я пользовался был (да и останется на всякий случай) - lc2kicad поставить, пока, можно из AUR:
yay -S lc2kicad
но репозиторий уже в архиве, а автор отписался, что проект всё.
И вот сегодня открыл для себя новый проект: easyeda2kicad.
И основная его фишка в том, что по указанному ID он может скачать сразу символ, посадочное место и 3D модель. Положить это в единое место к которому можно настроить пути и потом пользоваться централизованно.
Столкнулся с проблемой: при печати из Inkscape изображения получаются очень мелкими.
Гуглинг навёл на то, что это проблема с xdg-desktop-portal-kde. Парень из форма создал Bug Report в котором есть возможный WA. И там же есть отсылка на репорт в самом проекте Inkscape.
Если коротко: xdg-desktop-portal это некая сущность (или сучность?) которая позволяет приложениям на различных тулкитах более бесшовно интегрироваться в “неродные” окружения рабочего стола: Gtk в окружение KDE и Qt в окружения на базе Gtk (Gnome, Cinnamon, Mate & etc). Интеграция по большей части затрагивает только переиспользование стандартных системных диалогов, типа диалогов открытия файлов, сохранения, вывода окон предупреждений, диалогов печати (тут отдельный акцент). В общем, все те вещи, которые вроде более приятны глазу, но жить без них можно (“вам шашечки или ехать?”). Но и дополнительный слой абстракции, который сам по себе может нести баги.
Собственно проблема как раз и заключается в стыке разных сред при использовании диалога печати. Причём сначала поддержку Desktop Portal реализовали в Inkscape и сразу же это вызвало проблемы.
Ладно, теперь к сути. Мне ехать нужно. Решение в лоб это общесистемно заявить:
export GTK_USE_PORTAL=0
Собственно после чего все приложения Gtk в окружении KDE станут использовать Gtk диалоги. Как оказалось, если использовать в массе, так себе. К визуалу тоже быстро привыкаешь :)
Поэтому достаточно сделать следующее:
GTK_USE_PORTAL=0Теперь:
Если открывать через терминал ручками: inkscape file.svg, то имеет смысл завести alias с установкой переменной окружения в нужное значение. Если в скриптах (хммм), то указать явно в скрипте.
Когда ходили нонстоп после нефтебазы немного не туда сунулись по пути на Капитанский мостик, но возникло жаление по осени прогуляться тут с сыном, просто посмотреть, куда идут дороги. Сентябрь пришёл, время реализовывать планы. Что бы долго не тянуть выбрали 7 сентября.

Внезапный поход на вершину, которую ещё не доводилось сходить. Сходили 17-18 августа, но руки написать дошли только сейчас.

$ date +%j
256
С праздником всех причастных!