Кресты / Говнокод #26328 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
while ( port->available() )
        {
            au8Buffer[ u8BufferSize ] = port->read();
            u8BufferSize ++;

            if (u8BufferSize >= MAX_BUFFER) bBuffOverflow = true;
        }

Если буфер переполнился – попробуем это запомнить и... продолжим затирать память! Реальный кусок из библиотеки работы с RS485 – протоколом, применяющимся в промышленных контроллерах и все такое.

Запостил: smart smart, (Updated )

Комментарии (20) RSS

  • тип у u8BufferSize какой? если unsigned, то буфер кольцевой, но без указателя в нем смысл нет
    Ответить
      • А вдруг bBuffOverflow - это замапанный в память бит перезагрузки?
        Ответить
        • Перевёл на «WinAPI», проверь.
          #include <iostream>
          #include <cstdint>
          #include <windows.h>
          
          struct Port {
              uint8_t read()
              {
                  return 42;
              }
          
              bool available() const
              {
                  return isAvailable;
              }
          
              bool isAvailable = true;
          };
          
          Port portVal;
          Port *port = &portVal;
          constexpr size_t MAX_BUFFER = 64;
          uint8_t au8Buffer[MAX_BUFFER] = {};
          uint8_t u8BufferSize = 0;
          LPVOID flagAddr = nullptr;
          
          LONG handler(PEXCEPTION_POINTERS)
          {
              port->isAvailable = false;
              return EXCEPTION_CONTINUE_EXECUTION;
          }
          
          int main()
          {
              flagAddr = VirtualAlloc(nullptr, sizeof(bool), MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE | PAGE_GUARD);
              if (!flagAddr) {
                  std::cerr << "Couldn't allocate memory: error " << GetLastError() << std::endl;
                  return EXIT_FAILURE;
              }
          
              bool & bBuffOverflow = *reinterpret_cast<bool *>(flagAddr);
              PVOID handlerAddr = AddVectoredExceptionHandler(1, &handler);
          
              while ( port->available() )
                  {
                      au8Buffer[ u8BufferSize ] = port->read();
                      u8BufferSize ++;
          
                      if (u8BufferSize >= MAX_BUFFER) bBuffOverflow = true;
                  }
          
              std::cout << "Read " << static_cast<size_t>(u8BufferSize) << " bytes." << std::endl;
              // Read 64 bytes.
          
              RemoveVectoredExceptionHandler(handlerAddr);
              VirtualFree(flagAddr, 0, MEM_RELEASE);
          
              return EXIT_SUCCESS;
          }

          https://rextester.com/ODJIH52274
          Ответить
          • Боже, сколько напыщенного типоговна и приведений... Напоминает переливание из пустого в порожнее. В дэлфях это делается куда проще, без потери работоспособности кода.

            А если не видно разницы - зачем платить больше кодить на сях?
            Именно поэтому я за "дэлфи".
            Ответить
        • > замапанный в память
          тогда где разыменовывание? или это плюсомагия?
          Ответить
          • Это вполне может быть ссылка. Я вон выше перевёл.
            Ответить
            • > bool & bBuffOverflow = *reinterpret_cast<bool *>(flagAddr);

              я тебя понял, я просто не очень умю в кресты(((
              в сишечке так нельзя, там и ссылок-то нету


              а вообще легально так делать: взять, и костануть в ссылку? Это не будет уб нигде?
              Ответить
              • А в сишке это может быть глобалка, прибитая гвоздями к нужному адресу через линкерскрипт...
                Ответить
                • круто, а дай пример такого скрипта?)

                  я должен сделать сивол extern, а в линкер скрипте указать ему адрс?
                  Ответить
                  • > указать ему адрес

                    Да, там можно тупо присвоить значение символу (даже выражения всякие понимает). Либо описать новый регион памяти и хуйнуть в него секцию, в которой объявлены нужные переменные (тогда они даже не extern в общем-то, просто магически оказываются где надо).
                    Ответить
              • > а вообще легально так делать: взять, и костануть в ссылку? Это не будет уб нигде?
                Если по flagAddr находится bool — полностью легально. Я ж кастую прямо в bool, на который потом создаю ссылку. Если бы «flagAddr» был укококозателем нужного типа — можно было бы вообще без кастов написать «bool bBuffOverflow = *flagAddr».

                > в сишечке так нельзя, там и ссылок-то нету
                Можно прибить гвоздями, как Борманд предложил. В «msvc» это делается через «__declspec(dllimport) int hujLen;», а потом линкер смотрит во все прилинкованные .obj и ищет в них этот самый hujLen.
                Ответить
      • Моя цитата взята вот отсюда https://github.com/CONTROLLINO-PLC/CONTROLLINO_Library/blob/master/MEGA/DemoModbusRTUMaster/ModbusRtu.h – это либа, которая распространяется с типа "промышленным контроллером". Позор (

        А они сами позаимствовали этот код вот отсюда: https://github.com/smarmengol/Modbus-Master-Slave-for-Arduino

        Но видимо этот говнокусок много кто накопипастил.
        Ответить
        • >-for-Arduino
          О да. Там еще была реализация I2C, которая уходила в бесконечный цикл при возникновении ошибки на линии. Там еще на форуме (или стековерфлоу?) рекомендовали подтягивающие резисторы поставить, конденсаторы какие-то...
          Ответить

Добавить комментарий

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8