На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
Страницы: (2) 1 [2]  все  ( Перейти к последнему сообщению )  
> специализация шаблона функции для константной строки - литерала
    Цитата Wound @
    С чего вдруг?
    У него вызовется вот эта функция, при передаче массива.
    Цитата Qraizer @
    template <size_t length>
    void send(const char (&data)[length]) { send(&data, length-1); }

    Вот эта функция будет вызвана:
    ExpandedWrap disabled
      void send(const char *data) { send(data, strlen(data)); }
      Цитата ЫукпШ @
      Вот эта функция будет вызвана:

      С чего вдруг? Ты судя по всему не представляешь как работают шаблоны в С++
      Вот например: https://ideone.com/WDe9qp
      ExpandedWrap disabled
            #include <iostream>
            
            
            void send(const char *data)
            {
                std::cout << "void send(const char *data) " << std::endl;
            }
            
            template <size_t length>
            void send(const char (&data)[length])
            {
                std::cout << "void send(const char (&data)[length]) " << std::endl;
            }
            
            int main()
            {
                char msg[256] = { "Hello, world!" };
                char msg2[256] = "Hello, world!";
                send(msg);
                send(msg2);
                return 0;
            }


      Добавлено
      Просто я не понимаю, с чего вдруг компилятор должен делать неявный каст массива к указателю и вызывать эту функцию -> void send(const char *data), если есть сигнатура функции void send(const char [256] data), которая подходит безо всяких неявных кастов?
      Сообщение отредактировано: Wound -
        Цитата Wound @
        Просто я не понимаю, с чего вдруг компилятор должен делать неявный каст массива к указателю и вызывать эту функцию ->

        Да всё просто - я написал этот тест целиком и посмотрел как он работает.
        А что это - вообще не понятно:
        ExpandedWrap disabled
          void send(const char (&data)[length]) { send(&data, length-1); }

        Если мы хотим передавать массив (наинужнейшая функция), то зачем "length-1" ?
        Если мы хотим передавать строку (или строку в массиве), то для этого имеется уже подходящая
        функция. Её и использует компилятор.
        ---
        В некотором роде нагло и цинично можно заявить, что массив в "С" - это форма записи
        указателя. Который сразу проинициализирован на область памяти указанного размера.
        ---
        Тема в целом очень печальная.
        Очень не удачный вариант - совмещать формирование пакета с передачей.
        1. Что будет, если автора попросят сделать сборку x64 ?
        Скрытый текст

        как то раз без предупреждения администратор сервера заменил систему
        на версию x64. И по его уверениям, он сам даже не знал об этом.
        И всё должно было работать. Никого не волнует - как.

        2. Как различить структуры на стороне приёма ? Или, например, массив от строки ?
        Строки символов разных форматов (CP1251, UTF8, UTF16) ?
        ExpandedWrap disabled
          struct
          {
           char a;
           int b;
          };
          struct
          {
           int a;
           char b;
          }

        3. как вообще обнаружить окончание передачи ?
        4. А если попросят шифровать траффик ?
        5. А если поменять ключи компиляции (по выравниванию) ?
        итд итп...
        Сообщение отредактировано: ЫукпШ -
          Цитата ЫукпШ @
          А что это - вообще не понятно:
          Прочитайте первое сообщение темы.
            Цитата ЫукпШ @
            В некотором роде нагло и цинично можно заявить, что массив в "С" - это форма записи указателя.
            Садись, два. Сожги учебник, в котором так написано.
              Цитата ЫукпШ @
              Что будет, если автора попросят сделать сборку x64 ?
              Это маленькое устройство размером со спичечный коробок. 64 бита там излишни. А вот плюсы к Сям очень кстати.

              Даже стало интересно: а что сломается в этом коде, если его собрать под 64-битную целевую платформу? Я так сразу подводных камней не вижу. Уверен, что на 8- и 16-битных микроконтроллерах этот код будет работать так же, как сейчас работает на 32-битном.

              Цитата ЫукпШ @
              Как различить структуры на стороне приёма ? Или, например, массив от строки ?
              По посланному коду запроса.
              Цитата ЫукпШ @
              как вообще обнаружить окончание передачи ?
              Этим занимаются более нижние уровни протокола. Скажу по секрету - в начале пакета передается его длина. Бывают и другие варианты, byte-stuffing, например (пример можно найти в описании HDLC).
              Цитата ЫукпШ @
              А если попросят шифровать траффик ?
              Этим займутся более нижние уровни протокола, функции которых вызываются из send()
              Цитата ЫукпШ @
              А если поменять ключи компиляции (по выравниванию) ?
              У меня встречный вопрос как и про 64-битную целевую платформу: а что должно поломаться? указатель на void в параметрах глобальной функции передачи подразумевает невыровненные данные и именно с невыровненными данными идет работа. Так что от смены ключей компиляции кроме размера программы и пренебрежительно малого изменения времени реакции ничего не изменится.
              Сообщение отредактировано: Dushevny -
                ЫукпШ имеет в виду, что отсутствие типизации может привести к поломке протоколов обмена, когда одна из сторон делает это без согласования с другой. Например, передавая 64-битный int, когда приёсмная сторона ожидает 32-битный пакет, может быть неверно ею истолкован. Но это не проблема уровня сырого обмена данными, это должно решаться интерфейсами взаимодействия. Какой-нибудь std::basic_ostream<>::write() тоже не знает, что он пишет, и не может отвечать за то, как, верно или неверно, его посылку, считанную std::basic_istream<>::read(), будут потом парсить. Если тут и будут проблемы, то они явно относятся к уровню выше сырого обмена массивами байт.
                  Цитата Qraizer @
                  Например, передавая 64-битный int, когда приёсмная сторона ожидает 32-битный пакет,
                  Понятно. Для этого 20 лет назад в Стандарт Сей введен stdint.h, в котором объявлены (u)intXX_t и подобные. В мире микроконтроллеров "чистыми" int, short, long, long long пользуются только начинающие или те, кто учится на своих ошибках. Из фундаментальных типов используется только char и только для хранения символов, все остальное - только типы из stdint.h. Поэтому одни и те же куски кода я, например, использую на 8- 16- 32-битных контроллерах и на компе под 32- и 64-битными линухами и виндовсами.
                  0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                  0 пользователей:


                  Рейтинг@Mail.ru
                  [ Script execution time: 0,0439 ]   [ 16 queries used ]   [ Generated: 19.03.24, 06:35 GMT ]