Ответы пользователя по тегу C++
  • Как передать массив вместо аргументов?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Если я правильно понял вопрос, то наиболее похожее из того что мне известно -- это семейство функций getcontext/makecontext/setcontext/swapcontext и __builtin_apply. И то и другое -- не готовое решение, с форматом передаваемого участка памяти прийдётся разбираться, а __builtin_apply определённо завязано на архитектуру и ABI и это gcc-specific.

    Но я думаю, что это неправильный подход к решению и вообще сам вопрос -- неправильный подход к решению. Если ты пишешь транслятор, то для функций с фиксированным набором аргументов ты можешь тупо сгенерировать код вызова функции удовлетворяющий всем правилам C++.
    Ответ написан
  • Как из vector с int8_t получить int число?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Как получить то же самое в С++?

    например так:
    uint8_t foo[] = {7, 7};
    int i = foo[0] + 256 * foo[1];


    В js я могу получить это так
    Int8Array

    Скажи,
    - а что будет, если элемент массива foo будет иметь отрицательное значение?
    - а что будет, если твой код запустить на архитектуре с порядком байт big-endian?
    Ответ написан
  • Почему возникает ошибка?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    invalid abstract return type ‘Axis<unsigned int>’
    Почему возникает ошибка?

    Потому что Axis<unsigned int> -- абстрактный тип, а ты пытаешься вернуть объект такого типа.
    Скажи, что конкретно в сообщении об ошибке непонятно?
    Что с этим делать?
    - если тип не должен быть абстрактным -- смотреть в его иерархию наследования, искать недоопределённые чистые виртуальные функции и определять их или выкидывать.
    - если тип должен быть абстрактным -- пересмотреть свои взгляды на жизнь и начать возвращать либо ссылки, либо указатели на объекты абстрактного типа.
    Ответ написан
  • Почему тут ошибка?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    call of overloaded ‘Point2D()’ is ambiguous

    Потому что, похоже, у Point2D<T> больше одного конструктора по умолчанию.
    Ответ написан
    2 комментария
  • Как исправить ошибку линковки undefined reference?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Команда сборки:
    D:\mingw\mingw64\bin\g++.exe -fdiagnostics-color=always -g D:\running\code\parser.cpp -o D:\running\code\parser.exe

    Прости, но как по-твоему mingw должен из этой команды понять, что ты используешь какую-то библиотеку и слинковаться с ней?
    Тебе надо выполнить шаги по сборке библиотеки, а потом добавить её в свою команду сборки, типа того:
    D:\mingw\mingw64\bin\g++.exe -fdiagnostics-color=always \
    -g D:\running\code\parser.cpp \
    -L<путь куда ты установил libgq> -lgq \
    -o D:\running\code\parser.exe


    И я подозреваю, что поскольку gumbo-query это обёртка для gumbo, то когда ты успешно слинкуешься с libgq тебе прийдётся повторить эти шаги и для gumbo.
    Ответ написан
    1 комментарий
  • Почему в ассемблерном листинге gcc нет тела деструктора [complete object destructor]? Как его находит линкер?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Было бы логично увидеть, что происходит вызов deleting dtor внутри которого происходит вызов base object dtor.

    было бы логично, если бы ты вызывал delete для объекта. А для объекта на стеке-то зачем delete?

    Почему в ассемблерном листинге gcc нет тела деструктора [complete object destructor]?

    Есть, просто у тебя какой-то понтовый листинг и ты его не видишь. А из-под gcc -S для твоего кода выходит ассемблерный текст, в котором есть такие строчки:
    .globl  _ZN6ObjectD1Ev
    .set    _ZN6ObjectD1Ev,_ZN6ObjectD2Ev
    Ответ написан
  • Зачем обновляется указатель vptr внутри реализации виртуального деструктора, если внутри виртуальных деструкторов не используется виртуализация?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    внутри виртуальных деструкторов не используется виртуализация

    чего это "не используется"? А вот этот пункт стандарта для кого написан?
    Ответ написан
  • Как задать значение последней переменной?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Имеется код вида
    int64_t a = b/c
    b и c какие-то произвольные числа
    требуется записать 0 в переменную a, если произошел SIGFPE.
    Проверять значения b и c не вариант, нужно как-то задавать значение для a в обработчике сигнала.

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

    - наиболее простой и переносимый, но не самый быстрый -- таки проверить значения b и c перед вычислениями.

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

    - следующий вариант -- нифига не простой и не переносимый -- устанавливать обработчик сигнала с помощью sigaction, заказывать доставку SA_SIGINFO и анализировать ucontext (третий аргумент) в обработчике сигнала. Сложность заключается в том, что связь между тем, что будет записано в ucontext и исходным кодом на C ни разу не очевидна. Т.е. можно извлечь из памяти по адресу info->si_addr инструкцию вызвавшую сбой, проанализировать её длину и куда она записывает результат, записать в результат 0 и передвинуть адрес возврата. Но это выглядит как неоправданное количество мороки.
    Ответ написан
  • Что делать, если появляется непонятная ошибка после запуска c++ кода?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Что делать, если появляется непонятная ошибка после запуска c++ кода?

    Пытаться понять её -- универсальный рецепт.

    это исходный код.
    thread my_thread1(&connecter);
    if(connfd == true)

    В этом месте две ошибки. Первая -- ты сравниваешь int connfd с bool true, а вторая -- ты делаешь это без уважения потоконебезопасным способом. Прямо скажем, у тебя тут гонка между main и connecter. Когда ты эту гонку исправишь, жизнь твоя, скорее всего, наладится. Непонятно, правда, зачем ты вызываешь accept в параллельном потоке вместо того, чтобы сделать это синхронно, прямо в main.
    Ответ написан
    Комментировать
  • По какой причине метод не определён?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    По какой причине не видятся методы .x .y
    sqrt(x<T>()^2 + y<T>()^2);

    А почему ты думаешь, что это шаблонные методы? Вот здесь
    var_type name (var_type value = 0) { \
    определение совсем не шаблонное. Т.е. надо выкинуть <T>. А когда ты так сделаешь, x и y станут независимыми именами, и чтобы компилятор их нашёл в родительском классе надо будет либо добавить перед ними this->, либо как-нибудь ещё ему подсказать.
    Т.е. вот так должно бы работать:
    template<typename T>
    float DVector(2)<T>::length()
    {
        return sqrt(this->x()^2 + this->y()^2);
    }


    И, кстати, ^2 -- это (без дополнительных усилий) не возведение в квадрат.
    Ответ написан
  • Как исправить ошибку Memory limit?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Подозреваю, что дело в локальных переменных i и j в строках 42 и 43 и использовании какого-нибудь старого стандарта C++ продлевающего их области действия до конца охватывающего блока, из-за чего в check не отрабатывает условие в строке 30. Предлагаю убрать int в строках 42 и 43.
    Ответ написан
  • Массив указателей на функции. Почему программа не даёт результат?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Мне нужно выполнить функцию, из массива указателей на функцию, номер которой я укажу в консоли. Почему не выполняется?

    Потому что mass[0]; -- это не вызов функции, а просто указатель. Вызов функции выглядит так: mass[0]();
    Ответ написан
    Комментировать
  • Как исправить ошибку E0304?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Не понимаю, откуда эта ошибка появляется


    Здесь написано, что create_huge_matrix принимает два аргумента, и второй имеет такой же тип, как тип элементов внутреннего вектора:
    template <typename T>
    void create_huge_matrix(std::vector<std::vector<T>>& matrix, T lowerLimit);


    а здесь первый аргумент типа std::vector<std::vector<double>>, а второй -- int:
    create_huge_matrix(matrix_s, 5);

    а здесь вообще только один аргумент:
    create_huge_matrix(matrix_p);
    Ответ написан
    Комментировать
  • Как описать перегрузку оператора умножения?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    перегрузка оператора должна скалярно умножать два массива. Под этим подразумевается, например: массив1 - 3,2; массив2 - 5,1, скалярное умножение: 3*5 + 2*1 = 17

    LabArray operator* (const LabArray& other) {
          double sum = 0;
            for (int i = 0; i < size; ++i) {
              sum += Array[i] * other.Array[i];
            }
          return sum;
        }

    Если результатом должно быть число и возвращаешь ты double, то почему тип возвращаемого значения -- LabArray?
    Ответ написан
    Комментировать
  • Как проверить число ли подается на вход?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    isdigit

    проверяет, является ли символ цифрой или нет. Помогло бы вам, если бы вы получали из стандартного ввода строку и сами переводили её в число. Но нет, операция
    int count_students;
      cin >> count_students;

    вводит не строку, а число.

    Чтобы проверить, был ли ввод успешным или нет можно вызвать cin.fail(), типа того:
    cin >> count_students;
      if (cin.fail()) {
        cout << "Неправильные входные данные. Попробуйте еще раз.";
        cin.clear();
        cin.ignore();
        goto Step1;
      }
    Ответ написан
    1 комментарий
  • Как на Linux читать и изменять память процесса?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Классический способ состоит в использовании системного вызова ptrace с кодами запроса PTRACE_ATTACH для присоединения к процессу, PTRACE_PEEKTEXT и PTRACE_POKETEXT для чтения и записи его памяти и PTRACE_DETACH для отсоединения.
    Ответ написан
    Комментировать
  • Ne sovsem ponyatno kak ispravit, kto podskajet?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Ne sovsem ponyatno kak ispravit

    смотреть не туда, куда ты смотришь сейчас (не на определение COMPILE_TIME_ASSERT, с ним всё ок, оно такое, чтобы генерировать ошибку компиляции, когда какое-то условие в коде не выполняется), а в строку
    ../deps/source-sdk-2013/mp/src/public/tier0/threadtools.h:1130

    где этот assert сработал, и разбираться с ней.
    Ответ написан
    6 комментариев
  • В чем заключаются ошибки и как их исправить?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    А в чем заключаются эти ошибки, я не могу понять

    Когда ты на С++ пишешь строки подряд, вот так:
    "push edi"  
    "push esi"
    "mov edx,lenS"
    ...

    они склеиваются в одну строку. Когда ассемблер видит команду "push edipush esimov edx, lenS..." он резонно недоумевает.

    как их исправить

    Вставить символы конца строки \n или другие разделители инструкций в ассемблерный код.
    Ты же просил пример кода, вот же он, он компилируется и работает, воспользуйся им. Если непонятно что там написано, задавай вопросы.
    Ответ написан
  • Какие варианты есть здесь для реализации ассемблерной вставки?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    мне бы не помешали еще примеры хорошие

    вот тебе пример переставляющий первую и последнюю буквы:
    #include <iostream>
    
    int main()
    {
        char s1[] = "Hola queridos amigos";
        char tmp;
        asm ("mov (%[left]), %[tmp]\n\t"
             "xchg (%[right]), %[tmp]\n\t"
             "mov %[tmp], (%[left])\n\t"
             : [tmp] "=&q"(tmp)
             : [left] "r"(s1), [right] "r"(s1 + sizeof(s1) - 2)
             : "memory");
        std::cout<<s1<<std::endl;
        return 0;
    }
    Ответ написан
  • Ошибка с подключением к самописному ftp серверу, в чем проблема?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    в чем проблема?

    У тебя гонка между этим:
    if(pthread_create(&tid, NULL, new_connection, serv)) qDebug() << "ошибка создания потока подключения";
            server->num_of_users++;

    и этим:
    descriptor = *(server->sa[server->num_of_users-1]);


    С точки зрения работы с потоками код написан никак.
    Ответ написан