• Объясните простым языком, что делает команда git pull --rebase?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    что делает команда git pull --rebase?

    Делает pull, а потом делает rebase локальной истории на то что было получено через pull.
    Т.е. если в удалённом репозитории было
    A--B--C
    в локальном репозитории к этому было добавлено
    A--B--C--d--e
    а в удалённом
    A--B--C--D--E
    то после git pull --rebase локальная история станет такой:
    A--B--C--D--E--d'--e'
    где d' и e' -- это перебазированные поверх E локальные d и e.
    Ответ написан
    Комментировать
  • Как можно оптимизировать?

    @res2001
    Developer, ex-admin
    Это узкое место в вашей программе? Что-то не верится. Оптимизация не нужна.
    Ответ написан
    Комментировать
  • Что работает лучше: $3 vs $2.99?

    opium
    @opium
    Просто люблю качественно работать
    Ну блин что вы как маленький правильно делать зачеркнутая цена $10 а потом уже $2.99
    Ответ написан
    Комментировать
  • При подключении через ssh консоль перестает принимать комманды через 5 мин бездействия, как решить?

    Zoominger
    @Zoominger
    System Integrator
    заного

    Ох уж эти ноги.

    По теме:
    Загляните в файл /etc/sshd_config и поищите там строку типа "ClientAliveInterval", можно так:

    sudo cat/etc/sshd_config | grep Alive

    Какое там значение? Наверно, 300. Поставьте 3 600, например, это час бездействия.
    Ответ написан
    Комментировать
  • Что такое Си Runtime Library?

    @res2001
    Developer, ex-admin
    CRT - это реализация стандартной библиотеки Си/С++ для данного компилятора.
    ОС обычно пишутся на Си и если в ОС нет реализации функций из стандарта Си, то они реализуются в стандартной библиотеке. Все классы из stdlib С++ реализованы в CRT.

    CRT в VS может линковаться как статически так и динамически, в зависимости от опций компилятора. Линкуете статически - у вас распухает ваш исполняемый файл, динамически - пользователь должен предварительно поставить соответствующий vcredist (установку можно встроить в собственный инсталлятор). С точки зрения производительности оба варианта примерно одинаковы.

    Вы можете не использовать стандартную библиотеку в принципе (отключив ее опциями компилятора) и работать на прямую с ОС, но это накладывает много ограничений и вы фактически остаетесь с кастрированным вариантом ЯП, т.к. например в С++ даже стандартный new/delete, на сколько я знаю, реализованы в стандартной библиотеке и прямого аналога в ОС нет. Обычно этим никто не заморачивается из-за возникающих проблем, решение которых заметно увеличит время реализации проекта, разве что вам необходимо сделать исполняемый файл минимального размера, максимально быстро стартующий и без зависимостей.
    Ответ написан
    4 комментария
  • Как вызвать функцию другой программы на прямую (без API)?

    sergey-gornostaev
    @sergey-gornostaev Куратор тега Assembler
    Седой и строгий
    Люто сложная задача. В Windows можно попробовать с помощью CreateRemoteThread создать поток в адресном пространстве целевого процесса, с помощью SetThreadContext напихать в регистры параметры функции, а потом выполнить переход на её адрес. Правда, адрес надо ещё как-то узнать. Ну, и подозреваю, что у любого антивирусника от этого случится истерика.
    Ответ написан
    Комментировать
  • Где хранится размер памяти, которая выделена указателю?

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Начнем вот с этого: CppCon 2015: Andrei Alexandrescu “std::allocator I...

    На самом низком уровне память выделяется страницами или блоками. Принцип выделения зависит от особенностей организации ОС и самого железа. Освобождается память в точном соответствии с тем, как она была выделена.
    И обычный пользователь C++ этого ничего не видит.

    Оператор ::new является точкой обращения к аллокатору памяти процесса. К какому именно аллокатору идет обращение - как правило неизвестно. Это может быть dlmalloc, mimalloc или jemalloc. Их много и перечислять можно долго. Это может быть и самостоятельно созданный по мотивам доклада Александреску аллокатор.
    Каждый аллокатор, маркируя память как выделенную и передавая ее пользователю, каким-либо образом оформляет сервисную информацию о выделенном участке. Сервисная информация может храниться в заголовке, в памяти прямо перед отдаваемым пользователю адресом, может храниться в хвосте передаваемого пользователю участка памяти, а может храниться в совершенно отдельном пространстве памяти - в сервисном разделе.

    К чему это все. К тому что полностью точного ответа на твой вопрос дать не получится. Если бы в вопросе фигурировал конкретный аллокатор, то ответить можно было бы. Сейчас же ответить можно только что размер переданного пользователю блока памяти хранится в специальной сервисной информации, к которой и обращается функция освобождения памяти (не ::delete).
    Ответ написан
    1 комментарий
  • Сначала С, а потом С++?

    myjcom
    @myjcom Куратор тега C++
    Вопрос довольно короток. Есть ли смысл изучать сначала С, а потом С++?

    Ответ тоже довольно короток.
    Чем лучше программист знает С, тем труднее будет для него при программировании на С++ отойти от
    стиля программирования на С.

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

    Бьерн Страуструп. Язык программирования С++.

    Нотабене

    Тем не менее, хорошие программы на языке С по сути являются
    программами на С++. Например, все программы из классического описания С (K&R) являются
    программами на С++. В процессе изучения С++ будет полезен опыт работы с любым языком со
    статическими типами.

    Ответ написан
    1 комментарий
  • Как строка Сишного кода будет выглядеть на c++?

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

    @MarkusD Куратор тега C++
    все время мелю чепуху :)
    Предположим, есть общий шаблон сериализации данных для работы с абстрактными потоками ввода-вывода.
    Обобщенный шаблон такой сущности может выглядеть вот так.
    template< typename TValueType >
    struct Serializer final
    {
    	static inline const bool Read( const BasicStream& stream, TValueType& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const TValueType& value_storage );
    };


    У этого шаблона может присутствовать набор частных инстанцирований для простых и стандартных типов.
    Пример
    template<>
    struct Serializer<int8_t> final
    {
    	static inline const bool Read( const BasicStream& stream, int8_t& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const int8_t& value_storage );
    };
    
    // ...
    
    template<>
    struct Serializer<float> final
    {
    	static inline const bool Read( const BasicStream& stream, float& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const float& value_storage );
    };


    Любой пользователь библиотеки всегда может определить частное инстанцирование сериализатора для своего типа точно в такой же манере. А можно просто отдать свой пользовательский тип на откуп обобщенному шаблону.

    А теперь вкусненькое. Среди стандартных типов есть и std::string, и std::vector, и std::map. Если пользователь решит сериализовать весь контейнер своих пользовательских типов, нам не стоит обязывать его писать частное инстанцирование сериализатора для контейнера. Нам надо предусмотреть сериализацию любого стандартного контейнера с любым пользовательским типом.

    Мы это делаем с помощью частичной специализации шаблона сериализатора.
    Для произвольной строки
    template< typename TCharType, typename TCharTraits, typename TAllocator >
    struct Serializer<std::basic_string<TCharType, TCharTraits, TAllocator>> final
    {
    	static inline const bool Read( const BasicStream& stream, std::basic_string<TCharType, TCharTraits, TAllocator>& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const std::basic_string<TCharType, TCharTraits, TAllocator>& value_storage );
    };
    Для std::vector
    template< typename TElement, typename TAllocator >
    struct Serializer<std::vector<TElement, TAllocator>> final
    {
    	static inline const bool Read( const BasicStream& stream, std::vector<TElement, TAllocator>& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const std::vector<TElement, TAllocator>& value_storage );
    };
    Для std::pair
    template< typename TLeftElement, typename TRightElement >
    struct Serializer<std::pair<TLeftElement, TRightElement>> final
    {
    	static inline const bool Read( const BasicStream& stream, std::pair<TLeftElement, TRightElement>& value_storage );
    
    	static inline const bool Write( BasicStream& stream, const std::pair<TLeftElement, TRightElement>& value_storage );
    };


    И так далее.

    А вот как может выглядеть внешнее определение функции при частичной специализации.
    Пример чтения из стрима в вектор
    template< typename TElement, typename TAllocator >
    inline const bool Serializer<std::vector<TElement, TAllocator>>::Read(
    	const BasicStream& stream,
    	std::vector<TElement, TAllocator>& value_storage
    )
    {
    	size32_t stored_size;
    	Serializer<size32_t>::Read( stream, stored_size );
    
    	value_storage.resize( stored_size );
    	for( TElement& element : value_storage )
    	{
    		Serializer<TElement>::Read( stream, element );
    	}
    
    	return true;
    }
    Ответ написан
    8 комментариев
  • Как настроить сокеты беркли на разрыв соединения через определенное время?

    @res2001
    Developer, ex-admin
    Никак. Сокеты тут ни при чем - это логика вашего приложения. Взводите таймер и по срабатыванию закрывайте сокет сами.
    Ответ написан
    4 комментария
  • Есть ли жизнь на Линуксе?

    @etaliorum
    Платон мне друг, но истины не надо
    слезь с иглы виндусовского одобрения, сядь на линукс
    Ответ написан
    Комментировать
  • Компиляция c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    получается mainx узнает о том что есть функция printx() на этапе линковки [mainx.o] и [printx.o]?

    Да.

    Каким образом происходит передача информации в [mainx] что функция printx() существует?

    Это работа линковщика связывать ссылки на неопределённые символы с определениями этих символов.
    В main.o в месте вызова printx ставится команда вызова, в секции символов заводится неопределённый символ printx а в секции релокаций заводится запись, связывающая команду вызова с символом:

    objdump -dr mainx.o
    ...
    0000000000000000 <main>:
       0:   55                      push   %rbp
    ...
      3a:   89 c7                   mov    %eax,%edi
      3c:   e8 00 00 00 00          callq  41 <main+0x41>
                            3d: R_X86_64_PLT32      _Z6printxi-0x4
      41:   b8 00 00 00 00          mov    $0x0,%eax
      46:   c9                      leaveq 
      47:   c3                      retq   
    ...


    readelf -a mainx.o
    ...
    Relocation section '.rela.text' at offset 0x580 contains 12 entries:
      Offset          Info           Type           Sym. Value    Sym. Name + Addend
    ...
    00000000003d  001400000004 R_X86_64_PLT32    0000000000000000 _Z6printxi - 4
    ...
    
    Symbol table '.symtab' contains 25 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
    ...
        20: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _Z6printxi
    ...


    В printx.o в секции символов заводится символ, ассоциированный с адресом в коде, где определена функция printx:

    readelf -a printx.cpp
    ...
    Symbol table '.symtab' contains 24 entries:
       Num:    Value          Size Type    Bind   Vis      Ndx Name
    ...
        14: 0000000000000000    75 FUNC    GLOBAL DEFAULT    1 _Z6printxi
    ...

    Здесь value == 0 -- потому что printx оказалась по адресу 0 в секции .text.

    Линковщик объединяет входные секции согласно скрипту линковки, после чего вставляет конечные адреса символов в места, которые ссылаются на них.
    Ответ написан
    Комментировать
  • Куда поступать на программиста в Новосибирске после 9 или лучше после 11?

    kawabanga
    @kawabanga
    Есть неплохой шанс потерять мотивацию после 9го класса. Поэтому я все таки рекомендую закончить 11 класс.
    В 9 классе вы еще молоды, и многие ваши действия я бы отдал под контроль родителей. Опять же, колледж будет перенасыщен людьми, которые просто не смогли пойти в 10 класс. А это очень опасное окружение, которое может негативно сыграть на ваше будущее.

    А вот в 10-11 классе вы можете пойти в школы подготовки, вроде как они есть у нас тут в НСК. И уже к концу 11 класса будете иметь представление о том, куда вы планируете развиваться.

    Английский учите. Без вариантов. Впрочем, за 2 года вызубрить ЕГЭ - не думаю что это проблема.
    Ответ написан
    5 комментариев
  • Есть ли разница где ставить const для метода в c++?

    jcmvbkbc
    @jcmvbkbc
    "I'm here to consult you" © Dogbert
    Разница есть, и большая:

    const int get_NOD() {
        return NOD;
    }

    -- возвращает const int и может менять *this

    int get_NOD() const{
        return NOD;
    }

    -- возвращает int и не может менять *this.

    Нет разницы между

    const int get_NOD() {
        return NOD;
    }

    и

    int const get_NOD() {
        return NOD;
    }
    Ответ написан
    Комментировать
  • Зачем нужен std::unique?

    Taraflex
    @Taraflex
    Ищу работу. Контакты в профиле.
    https://ru.cppreference.com/w/cpp/algorithm/unique - расписано яснее некуда.
    Для хранения множества уникальных элементов просто используйте std::set или std::unordered_set
    Ответ написан
    5 комментариев
  • Реализация конечного цикла без проверки условия выхода?

    RiseOfDeath
    @RiseOfDeath
    Диванный эксперт.
    Нет не возможно. У вас в любом случае будет условие. Чисто логически чтобы цикл кончился он должен кончится по какой-то причине, в отсутствии причины он не кончится.

    Другое дело, что можно кончить цикл всячески, не только "адекватно". Теоретически вы можете поменять значение PC регистра (Хотя емнип на x86 его нельзя редактировать напрямую). Но опять же если вы просто поменяете безусловно - это не цикл у вас получится, а если условно - вот вам условие выхода.

    p.s.

    У вас вообще цикла нет - вы используете (в сильно неявном,извращенном виде) рекурсию. И она тоже буде или бесконечной (пока стек не кончится) или с условием прерывания.

    p.p.s.
    А вообще не занимайтесь ерундой.

    По воводу того, как оно работает:
    Смотрим этот кусок кода:
    (arg / N) * ((int)CycleEnd - (int)CycleIteration)
    Вы вычитаете разницу между адресами функций CycleIteration и CycleEnd (я так понимаю, там должно получится -1 * sizeof(void*). Затем вы это умножаете (arg / N) (вы делите целое число на целое число, емнип оно округляется в меньшую сторону, а не по правилам математики). Кроме последней итерации (когда arg = N) у вас будет результат ноль. Т.е. вы от указателя CycleIteration отнимаете 0 и присваиваете это ptr.
    Фактически (кроме последней итерации) ptr указатель на функцию CycleIteration (вы ее вызываете рекурсивно).
    Когда arg == N вы умножаете ваш -1 * (sizeof(void*)) на 1 и таким образом вы присваиваете ptr значение CycleIteration - 1*sizeof(void*) т.е. на CycleEnd.

    Вообще этот код работает ровно по двум причинам:
    1. Вы не уперлись в размер стека в вашей рекурсии (как я говорил выше это рекурсия).
    2. Вам повезло, что функции в памяти расположены так же, как и в коде. Если линковщику вздумается поменять их местами - ваш код не будет работать (так, как вы ожидаете).
    Ответ написан
    2 комментария
  • Реализация конечного цикла без проверки условия выхода?

    Adamos
    @Adamos
    Главная фишка - в том. что arg / N == 0 до тех пор, пока arg < N.
    Функция-итератор вызывает функцию ptr по адресу.
    Адрес вычисляется по формуле "адрес функции-итератора плюс то самое выражение arg / N, умноженное на разницу адресов функции-итератора и функции-конца цикла.
    Вместо банального сравнения используется математическое выражение, вот и вся хитрость.
    И да, Antony прав - это не чистый цикл, а просто извращенная рекурсия.

    P.S. Кстати, можно превратить это извращение и в цикл - создаем вектор адресов функций, заполняем его нужным количеством адресов функции, изменяющей переменную цикла, а в конец добавляем адрес завершающей функции. Проходим по нему, ничего не проверяя... зато без рекурсии ;))
    P.P.S. Хотя вектор здесь тоже не нужен. Просто массив из двух значений и индексом - то самое выражение.
    Ответ написан
    1 комментарий
  • Как правильно вести и заканчивать проекты?

    tema_sun
    @tema_sun
    Проект не надо заканчивать. Его надо запускать как можно быстрее и потом итеративно развивать.
    Не удивительно, что ни в одной кинги по программированию про это не пишут. Ведь к собственно навыку написания кода это отношения не имеет никакого.
    Ответ написан
    3 комментария