Задать вопрос
Ответы пользователя по тегу C++
  • Какой приоритет операций, разворачивающихся из fold-expression?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Согласно eel.is/c++draft/expr.prim.fold#nt:fold-operator и eel.is/c++draft/temp.variadic#14 чтобы получить то что ты хотел (и что стандарт называет термином "binary left fold") вместо cout << (args << ...) << endl; надо было написать (cout << ... << args) << endl;

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

    Потому что у тебя получился binary right fold.

    Какой приоритет операций, разворачивающихся из fold-expression?

    Поскольку операция одна и та же, приоритет одинаковый. Свойство о котором ты говоришь называется "ассоциативность". binary right fold ассоциирует подвыражения справа налево, binary left -- слева направо.
    Ответ написан
    3 комментария
  • Почему не собирается kaldi?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Вот вывод ошибки make test в директории src

    1) зачем запускать make test в каталоге src, когда у проекта есть система сборки основанная на CMake и можно запускать make test в каталоге где выполняется сборка?
    2) на ubuntu 22.04.5 c libblas-3.10.0, liblapack-3.10.0 и libatlas-3.10.3 сборка завершается успешно и make test в каталоге сборки тоже завершается успешно: 100% tests passed, 0 tests failed out of 132

    Команда компиляции для первого файла из приведённого лога с ошибкой при этом такая:
    cd /home/jcmvbkbc/tmp/tests/1390844/kaldi/build/src/matrix && /usr/bin/c++ -DHAVE_CLAPACK=1 -DKALDI_NO_PORTAUDIO=1 -Dkaldi_matrix_EXPORTS -I/home/jcmvbkbc/tmp/tests/1390844/kaldi/build/_deps/openfst-src/src/include -I/home/jcmvbkbc/tmp/tests/1390844/kaldi/tools/CLAPACK -I/home/jcmvbkbc/tmp/tests/1390844/kaldi/src/matrix/.. -I/home/jcmvbkbc/tmp/tests/1390844/kaldi/src/base/.. -fPIC -std=c++14 -MD -MT src/matrix/CMakeFiles/kaldi-matrix.dir/kaldi-matrix.cc.o -MF CMakeFiles/kaldi-matrix.dir/kaldi-matrix.cc.o.d -o CMakeFiles/kaldi-matrix.dir/kaldi-matrix.cc.o -c /home/jcmvbkbc/tmp/tests/1390844/kaldi/src/matrix/kaldi-matrix.cc
    Ответ написан
    1 комментарий
  • Как link`овать fasm + c(++)?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    я починил эту ос, теперь хотел понемногу добавлять C, т.к. на чистом ассемблере далеко не уйдешь. Если получится запустить хоть Hello, World! - буду очень благодарен

    Я положил эту ос на github и приделал к ней Makefile и hello world на C: https://github.com/jcmvbkbc/toster-1388736
    Потестировать можно набрав make run и введя команду hello в консоли внутри qemu.

    Я, однако, не стал интегрировать этот код на С с кодом на ассемблере. Потому что у кода на ассемблере есть пара проблем:
    - код на ассемблере хардкодит координаты бинарников на диске, загружает их в фиксированные адреса в памяти и переходит прямо на них. Это стрёмная практика, я не стану её поощрять.
    - этот код 16-битный, для реального режима, можно, конечно, растить его дальше, но куда практичнее было бы переключиться в нормальный защищённый режим, 32- или 64-битный, что одно, что другое не так уж сложно.
    - код "ядра" не предоставляет никаких сервисов "приложениям", он только загружает их в память и запускает. Фактически это не ядро а загрузчик для baremetal приложений.

    Иными словами, в ответ на вопрос из топика "Как link`овать fasm + c(++)?" скажу, что в данном случае линковать, в смысле используемом в контексте компиляторов, не имеет смысла.
    Ответ написан
    7 комментариев
  • Почему ОС запускается на QEMU, а на Virtual Box нет?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Почему ОС не запускается на Virtual box, а на QEMU запускаеться?

    Потому что QEMU TCG не очень точно эмулирует x86. Если в командную строку qemu добавить -enable-kvm, то оно тоже не будет работать.

    А вот если добавить ret в реализацию GDT::load_gdt() и не вызывать load_tss() то оно начинает в qemu-kvm работать:
    diff --git a/src/GDT/GDT_impl.s b/src/GDT/GDT_impl.s
    index 4f69835abd9d..5476837f3d0a 100644
    --- a/src/GDT/GDT_impl.s
    +++ b/src/GDT/GDT_impl.s
    @@ -2,6 +2,7 @@
     .extern _ZN8SimpleOS3GDT7gdt_ptrE
     _ZN8SimpleOS3GDT8load_gdtEv:
            lgdt _ZN8SimpleOS3GDT7gdt_ptrE
    +       ret
     
     .global _ZN8SimpleOS3GDT8load_tssEv
     _ZN8SimpleOS3GDT8load_tssEv:

    Подозреваю, что и в virtual box оно заработает.
    Проблема в загрузке TSS, короче. Мне не знакомы дебри TSS, но для поверхностного взгляда кажется странным то, что все сегментные селекторы в твоём TSS имеют RPL=3, а селектор стека -- RPL=0.
    Если ты хочешь разбираться с тем, что происходит, то разумно было бы поменять порядок инициализации, сначала загрузить IDT, чтобы иметь возможность обрабатывать исключения, а потом загружать TSS и смотреть, что за исключение эта операция выкидывает.
    С другой стороны, непонятно зачем в текущей версии этой ОС нужен TSS. Подозреваю, что никакая функциональность не будет потеряна, если его не загружать.
    Ответ написан
    Комментировать
  • Расскажите пожалуйста как реализован sin в cmath?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    кода я не нашел, или плохо искал

    вот код из glibc.

    через ряд тейлора не вариант при больших значениях угла ряд медленно сходится

    В приведённой реализации сначала аргумент приводится к диапазону ±pi/2, потом берётся фиксированное число слагаемых ряда тейлора.
    Ответ написан
    1 комментарий
  • Как исправить ошибку в MakeFile?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ругается на g++ -I $(INCL) $(SRCS) -o $(TARGET), как можно исправить?

    Заменить пробелы в начале строки одним табом. Команды в makefile начинаются с табов.
    Ответ написан
    Комментировать
  • Почему название файла в моей ОС изменяется само?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Проблема, как я вижу, зарыта в реализации метода map::copy, вот в этом месте. Нельзя копировать сложные объекты функцией memcpy(), потому что при удалении копии её деструктор освободит данные оригинала. Для такого копирования следует либо использовать placement new, либо копировать целиком объект Node, типа того. Для того чтобы это работало потребуется реализовать глобальный оператор new, типа того. С этими изменениями конкретно описанная в топике проблема решается, но я вижу, что и другие методы класса map реализованы с похожими ошибками, так что не расслабляйся и не думай, что это была единственная проблема в коде.

    Отдельный вопрос: зачем FileSystem::get_root() копирует всё дерево файловой системы, когда FileSystem::tree() явно не собирается его менять, можно было бы в этом случае обойтись константной ссылкой.
    Ответ написан
    1 комментарий
  • Не работает таблица прерываний(IDT). Что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    В чем может быть проблема?

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

    Вот эта структура:
    struct IDTPtr {
        uint16_t limit;
        uint32_t base;
    };

    должна быть определена с атрибутом packed, иначе компилятор вставляет паддинг для выравнивания поля base на границу uint32_t, из-за чего в IDT загружается неверный адрес.

    Ну и, вдобавок, нельзя делать iret из середины с++-функции, потому что компилятор организовал в ней кадр стека и вместо возврата iret снимает и интерпретирует мусор из этого кадра:
    001000e6 <SimpleOS::IDT::dividing_by_zero()>:
      1000e6:       55                      push   %ebp
      1000e7:       89 e5                   mov    %esp,%ebp
      1000e9:       53                      push   %ebx
      1000ea:       83 ec 04                sub    $0x4,%esp
      1000ed:       e8 15 01 00 00          call   100207 <__x86.get_pc_thunk.ax>
      1000f2:       05 06 11 00 00          add    $0x1106,%eax
      1000f7:       83 ec 0c                sub    $0xc,%esp
      1000fa:       8d 90 08 fe ff ff       lea    -0x1f8(%eax),%edx
      100100:       52                      push   %edx
      100101:       89 c3                   mov    %eax,%ebx
      100103:       e8 4c 00 00 00          call   100154 <SimpleOS::Terminal::print(char const*)>
      100108:       83 c4 10                add    $0x10,%esp
      10010b:       fa                      cli
      10010c:       cf                      iret
      10010d:       90                      nop
      10010e:       8b 5d fc                mov    -0x4(%ebp),%ebx
      100111:       c9                      leave
      100112:       c3                      ret
    Ответ написан
    9 комментариев
  • Error: no multiboot header found при загрузке своей ОС, как исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Нужны подробности сборки. Согласно спецификации заголовок multiboot должен быть в пределах 8192 байт от начала, но если в сборку не подсовывать никаких дополнительных ключей и потом пытаться загружать elf-файл, то в нём multiboot header может оказаться дальше 8К от начала:

    $ gcc -m32 boot.s -nodefaultlibs -nostartfiles -Wl,-Tlinker.ld -no-pie -o boot.elf
    $ readelf -S boot.elf
    There are 8 section headers, starting at offset 0x3140:
    
    Section Headers:
      [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
      [ 0]                   NULL            00000000 000000 000000 00      0   0  0
      [ 1] .note.gnu.bu[...] NOTE            00100000 001000 000024 00   A  0   0  4
      [ 2] .multiboot        PROGBITS        00101000 003000 00000c 00      0   0 4096
      [ 3] .text             PROGBITS        00102000 002000 000009 00  AX  0   0 4096
      [ 4] .bss              NOBITS          00103000 003000 004000 00  WA  0   0 4096
      [ 5] .symtab           SYMTAB          00000000 00300c 0000a0 10      6   9  4
      [ 6] .strtab           STRTAB          00000000 0030ac 00004d 00      0   0  1
      [ 7] .shstrtab         STRTAB          00000000 0030f9 000044 00      0   0  1
    Key to Flags:
      W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
      L (link order), O (extra OS processing required), G (group), T (TLS),
      C (compressed), x (unknown), o (OS specific), E (exclude),
      D (mbind), p (processor specific)


    При такой сборке секция .multiboot оказалась по смещению 0x3000.
    Ответ написан
    Комментировать
  • Как ATmega88 подружить с кодом на С++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Сигналы доходят до меги, но она не включает ни один из светиков.

    Я бы начал с отладки простым безусловным включением led на старте программы. Потому что 1К резистор последовательно со светодиодом с падением в 2В ограничивает ток 3ма, чего, скорее всего, недостаточно для заметного свечения.
    Ответ написан
    Комментировать
  • Try/catch и goto?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Для выхода из вложенных циклов при try/catch в случае исключения произойдёт свертка стека

    stack unwinding или развёртка стека происходит при выходе из одного или более вложенных вызовов, т.е. когда текущим должен стать более ранний кадр стека. При выходе из вложенных циклов в пределах одной функции кадр стека не меняется, но по правилам языка автоматические переменные из покинутых блоков должны быть уничтожены. Компилятор генерирует для этого код вызова деструкторов и вставляет его вызовы на пути выхода из блоков. В случае stack unwinding компилятор генерирует код вызова деструкторов, но вызов этого кода происходит более сложным путём. О том, как делается stack unwinding в gcc почитать можно здесь, о том как в этот процесс встраивается вызов деструкторов -- здесь.

    будет ли тоже самое для goto?

    То же самое будет и для goto.
    Ответ написан
    Комментировать
  • Почему время выполнения программы так сильно различается?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    … 75% cpu 2:23,52 total
    … 113% cpu 1:22,71 total
    … 73% cpu 2:20,75 total
    количество потоков в программе равно количеству потоков процессора (в моём случае - 8…

    Похоже, что твоя программа не справляется с загрузкой всех ядер, едва одно ядро она нагружает. Я бы смотрел в то как потоки взаимодействуют друг с другом и искал там явную или скрытую сериализацию.
    Ответ написан
    Комментировать
  • Как создать диалоговое окно без ресурсов?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как быть?

    CreateDialogIndirect принимает на вход в параметре lpTemplate указатель на структуру описывающую диалог.

    понял что проект VS обязательно должен быть оконным, в противном случае тупо не будет ресурсов

    вроде нет никаких ограничений по прикреплению ресурсов к консольным приложениям. Версия-то у них есть, а это же тоже ресурс.
    Ответ написан
    Комментировать
  • Почему теряется часть массива символов при его передаче по сокету?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    выяснил что проблема в sizeof(buf) который почему то равен 8 после передачи в функцию

    https://qna.habr.com/answer?answer_id=2411176#answ...
    Ответ написан
    Комментировать
  • Как можно разделить данный код (см. ниже) по header'ам и cpp'ам, учитывая зависимости в нём?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    как я могу это сделать?

    Разносишь определения классов по файлам *.h. Разносишь определения методов классов по одноимённым файлам *.cc, инклудишь в них одноимённые *.h Потом смотришь на свою картинку. Стрелки наследования и агрегации добавляют include <файл в конце стрелки> в h файл в начале стрелки. Стрелки использования добавляют include <файл в конце стрелки> в cc файл в начале стрелки.
    Ответ написан
    1 комментарий
  • Как исправить ошибку буфера с UART?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    ONESTOPBIT ломало передачу блока

    Передачу откуда куда?

    DWORD ComIface::write(byte* data, int count)

    Что конкретно эта функция должна делать? Если это просто запись count байтов, то зачем так сложно?

    DWORD ComIface::read_block(byte* buffer, int size)

    Что конкретно эта функция должна делать?


    hpet rt;
        while (get_stats().cbInQue < size) {
            if (!SetCommMask(port_handle, EV_RXCHAR)) {
                printf("SetCommMask failed with error %d.\n", GetLastError());
                return NumberOfBytesRead;
            }
            WaitCommEvent(port_handle, &status, &overlap);
            WaitForSingleObject(overlap.hEvent, read_delay);
            if (rt.get_ms_dt_weak().count() > read_delay * size) {
                return NumberOfBytesRead;
            }
        }


    Что здесь происходит?

    Какие проблемы приводят к такому и как это чинить?

    Чтобы что-то чинить нужно это сначала понять.
    Ответ написан
  • Функция не работает, не понимаю почему, как можно исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что я сделал не так, подскажите пожалуйста
    if (b[i] >= x || b[i] <= y) {
      a[j] = b[i];
      j++;
    }
    ...
    if (b[i] < x || b[i] > y) {
      a[j] = b[i];
      j++;
    }

    Условия в операторах if не являются взаимоисключающими, а значит j может стать больше чем n и запись в a[j] вылезет за границу массива.
    Я не уверен в правильности первого условия, но особо не задумываясь можно второе условие переписать как прямое отрицание первого: if (!(b[i] >= x || b[i] <= y)) и это гарантирует, что индекс не выйдет за пределы массива, вне зависимости от правильности первого условия.
    Ответ написан
    Комментировать
  • Ошибка С2360, initialization of 'hInstanse' is skipped by 'case' label, почему?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    initialization of 'hInstanse' is skipped by 'case' label, почему?
    switch (uMsg)
    {
    ...
    case WM_CREATE:
    //получаем дескриптор приложения
    HINSTANCE hInstance = GetModuleHandle(0);
    ...
    break;
    
    case WM_MOUSEMOVE:
    //устанавливаем тот или иной курсор в зависимости от местонахождения мыши
    ...

    Потому что -- посмотри в этот код -- это фактически так: перейдя на метку WM_MOUSEMOVE код попадёт в область где hInstance определён, но минует его инициализацию. Компилятор туповат, чтобы понять, что hInstance дальше не используется. Простейший фикс -- обернуть код обработчиков в блоки:
    switch (uMsg)
    {
    ...
    case WM_CREATE:
    {
      //получаем дескриптор приложения
      HINSTANCE hInstance = GetModuleHandle(0);
      ...
    }
    break;
    
    case WM_MOUSEMOVE:
    {
      //устанавливаем тот или иной курсор в зависимости от местонахождения мыши
      ...
    }
    ...
    Ответ написан
    1 комментарий
  • Ошибка в подсчете символов, что делать?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    считать количество русских букв, однако он не правильно это делает, что не так?

    считать русские буквы сложно, твой код зависит от кодировки и в любой не-однобайтной кодировке этот код не будет работать правильно. Проще всего, мне кажется, выкинуть charVector и весь код связанный с ним, а оставшееся переписать следующим образом:
    setlocale(LC_ALL, "");
    
    const char *str = input.c_str();
    
    while (*str) {
        wchar_t c;
        int n = mbtowc(&c, str, MB_CUR_MAX);
    
        if (n < 0)
            break;
        if (wcschr(L"абвгд...юя", c))
            ++count;
        str += n;
    }
    Ответ написан
    1 комментарий
  • Как правильно вывести структуру из dll на c++ в Python?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Возврат структуры по значению при определённых условиях (связанных с размером и типами данных полей структуры) добавляет скрытый параметр (указатель на область памяти куда нужно вернуть результат), который функция будет ожидать. Это твой случай, и поэтому все остальные параметры съехали на один. Решение -- либо научить ctypes тому, что возвращается сложный тип и у функции может быть скрытый параметр (полагаю, что так: ctypes.restype(outdata), где outdata -- тип rez1, см), либо переделать функцию так, чтобы она не требовала скрытого параметра (например, добавив явный указатель на результат в список параметров, см).
    Ответ написан
    4 комментария