Общий размер структуры

Тема в разделе "ESP8266, ESP32", создана пользователем AlexVS, 16 июн 2020.

  1. Igor68

    Igor68 Гуру

    Что касается скобок - привычка, потому как "считать" легче в длинных выражениях. Даже когда решал примеры в математике - давно было.
    Что касается для кого сие слова - для тех кто говорит типа "код не верный", на всех платформах будет одинаково. Смотрите #73 (PS Сформированный массив на одной платформе может быть не корректен при приёме его на другой.)
    Это на одной платформе:
    Код (Text):
    igor@debianNUC7PJYH:~/coding/GCC/test$ ./test
    buffer:
    00 00 00 00 00 F0 F1 F2 F3 F4 F5 F6 F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    test: sz=32 val=-579005069656919568

    igor@debianNUC7PJYH:~/coding/GCC/test$
    Это на другой:
    Код (Text):

    www-data@Moxa:~/ramdisk$ ./test
    buffer:
    00 00 00 00 F0 F1 F2 F3 F4 F5 F6 F7 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    test: sz=32 val=-579005069656919568
    www-data@Moxa:~/ramdisk$
     
    Оба работают одинаково, но байты расположены не одинаково. Если с одной платформы передать в другую, то она прочитает бардак. Про это вообще-то вся эта тема, и из-за этого я попал сюда. Дабы обратили внимание в построении(организации) структур с разными типами данных, а так же массивов данных.

    PS: А интересно... что за дела? Говоришь по одно, понимают другое типа:
    - Вода прозрачная
    - Да верно, луна высоко... не достать
    Даже не знают кто такой "Бык театральный"... посмотрите фильм "Каникулы строгого режима", там есть это крылатое выражение.
     
    Последнее редактирование: 18 дек 2020
  2. SergeiL

    SergeiL Оракул Модератор

    Да, теперь вижу, сразу не заметил.
    Вот и получается, что если бы использовать обычные структуры, с отключением выравнивания через #pragma pack, результат был бы корректный, так как он стандартный, и мы четко говорим компилятору чего хотим.
    А тут компилятор не знает наших мыслей :(
     
    Последнее редактирование: 18 дек 2020
    Igor68 нравится это.
  3. Igor68

    Igor68 Гуру

    Ну наконец-то услышали:)
    Что касается #pragma pack, то почему-то на разных компиляторах (даже GCC) этих двух платформ пишутся по разному... в одном случае с параметрами, в другом без. Почему не знаю, потому им и не пользуюсь, а располагаю данные вручную... в структурах первыми идут самые "тяжелые" и далее по мере их "облегчения". Потому как заголовочные файлы для обеих платформ одни и те же... помогает но, не всегда - может где и накосячил. А испытываю работоспособность постоянно на разных платформах (для того и держу MOXA UC-7112Lx-Plus с кросс-компилятором).
     
    Последнее редактирование: 18 дек 2020
  4. Igor68

    Igor68 Гуру

    Дались Вам эти скобки! Почерк у меня такой - с наклоном влево наверное... ну люди читают и не жалуются. Разве в этом смысл? Тема-то другая!
     
  5. b707

    b707 Гуру

    Игорь, вы мою редакцию кода запускали?

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

    Если у вас из массива после передачи читается бардак - значит ищите ошибки В СВОЕМ КОДЕ.

    А скобки вы расставляете неверно... и опять все списываете на привычку... как уже было со ссылками на массивы
     
  6. b707

    b707 Гуру

    опять двадцать пять! Вы уже писали про то что тема другая. когда я вам ссылку на массив обьяснял, хотя это непосредственно связано с вашими ошибками.

    В программировании нет мелочей.
     
  7. Igor68

    Igor68 Гуру

    Фраза "как-нибудь" не прокатывает - должно работать на всём! Что касается компилятора - то он поставляется на диске с устройством (кросс-компилятор) и ориентируюсь на него. А работать должно и на PC Debian(один GCC), и на MOXA IA240/UC-7112Lx-Plus(другой GCC), и на MOXA UC-7101Lx(третий GCC), и на UNO-1019 VindowsCE(VisualStudio), и на PC WindowsXP(VisualStudio), и на новой вЕнде(не делал пока но вижу придется). И везде #pragma pack со своим подподвыподвертом. Не проще ли универсально сформировать структуру для обмена по сети между ними всеми? И впихнуть её в один заголовочный файл. Я не умею так, как ребята с ГитХаба сразу для всего, да ещё и с учетом возможной кросс-компиляции.
     
  8. Igor68

    Igor68 Гуру

    Вот код
    Код (C++):
    #include <stdio.h>
    #include <stdint.h>

    #define _sz     32
    uint8_t         buf[_sz];

    void f1(uint8_t* buff, uint8_t* ptr) {
            buff = ptr;
    }

    int64_t f2(uint8_t *buff) {
            return *((uint64_t*)buff);
    }

    int main(void) {
            uint64_t        par = 0xF7F6F5F4F3F2F1F0;
            int     cnt = 0;
            uint8_t *bbuf = buf + 5;
            f1(bbuf, (uint8_t*) &par);
            par = f2(bbuf);
            printf("buffer:\n");
            while(cnt < _sz) {
                    printf("%02X ", buf[cnt]);
                    cnt++;
            }
            printf("\ntest: sz=%i val=%lli\n", sizeof(buf), par);
            return 0;
    }
    вот Makefile:
    Код (Bash):
    ###########################
    # Simple Generic Makefile #
    ###########################

    #CC=terminal-gcc

    CC=gcc

    #PREFIXPATH=/usr/local/arm-linux/bin
    #CC=$(PREFIXPATH)/arm-linux-gcc

    #STRIP=$(PREFIXPATH)/arm-linux-strip
    #NAME=proxy


    CFLAGS=-c -Wall -O2
    LDFLAGS=-lpthread

    #SOURCES=*.c
    SOURCES=$(shell ls *.c)

    OBJECTS=$(SOURCES:.c=.o)
    EXECUTABLE=test

    all: $(SOURCES) $(EXECUTABLE)

    $(EXECUTABLE): $(OBJECTS)
        $(CC) $(LDFLAGS) $(OBJECTS) -o $@

    .c.o:
        $(CC) $(CFLAGS) $< -o $@

    install:
        install -m 0755 $(EXECUTABLE) $(HOME)/local/bin

    clean:
        rm -rf *o $(EXECUTABLE)
    Вот компиляция и запуск в консоли:
    Код (Text):
    igor@debianNUC7PJYH:~/coding/GCC/test$ make
    gcc -c -Wall -O2 main.c -o main.o
    main.c: In function ‘main’:
    main.c:56:29: warning: format ‘%i’ expects argument of type ‘int’, but argument 2 has type ‘long unsigned int’ [-Wformat=]
             printf("\ntest: sz=%i val=%lli\n", sizeof(buf), par);
                                ~^              ~~~~~~~~~~~
                                %li
    main.c:56:38: warning: format ‘%lli’ expects argument of type ‘long long int’, but argument 3 has type ‘uint64_t’ {aka ‘long unsigned int’} [-Wformat=]
             printf("\ntest: sz=%i val=%lli\n", sizeof(buf), par);
                                       ~~~^                  ~~~
                                       %li
    gcc -lpthread  main.o -o test
    igor@debianNUC7PJYH:~/coding/GCC/test$ ./test
    buffer:
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    test: sz=32 val=0

    igor@debianNUC7PJYH:~/coding/GCC/test$ ./test
    buffer:
    00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
    test: sz=32 val=0
    igor@debianNUC7PJYH:~/coding/GCC/test$
     
     
  9. b707

    b707 Гуру

    да, тут уже я ошибся.
    Вот правильно:
    Код (C++):
    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>

    #define _sz     32
    uint8_t         buf[_sz];

    void f1(uint8_t* buff, uint8_t* ptr, size_t _size) {
            memcpy(buff, ptr, _size);
    }

    uint64_t f2(uint8_t *buff) {
          uint64_t result =0;
            memcpy(&result, buff, sizeof(result));
           return result;
    }

    int main(void) {
            uint64_t        par = 0xF7F6F5F4F3F2F1F0;
            int     cnt = 0;
            uint8_t *bbuf = buf + 5;
            f1(bbuf, (uint8_t*) &par, sizeof(par));
            par = f2(bbuf);
            printf("buffer:\n");
            while(cnt < _sz) {
                    printf("%02X ", buf[cnt]);
                    cnt++;
            }
            printf("\ntest: sz=%i val=%llu\n", sizeof(buf), par);
            return 0;
    }
    Кстати. Игорь, вы намеренно "стреляете себе в ногу", обьявляя par сначала как беззнаковую переменную, а потом выводя результат из процедуры f2() как int64_t и печатая его в printf как знаковый?
     
    Igor68 нравится это.
  10. AlexU

    AlexU Гуру

    Что-то не могу понять -- кто над кем стебётся.
    Пользователь b707 над пользователем Igor68, выкладывая не рабочий код, с просьбой его проверить. Или Igor68 над b707, проверяя заведомо не правильный код, с сообщением о результатах работы этого кода.


    Немного опоздал.....
     
    Igor68, b707 и parovoZZ нравится это.
  11. b707

    b707 Гуру

    тут безусловно моя вина.
    Не стебался. просто написал требухню и выложил, не проверив.
    Последний вариант уже сначала прогнал на соседнем линуксе, а потом выложил
     
    Igor68 нравится это.
  12. SergeiL

    SergeiL Оракул Модератор

    Думаю этот код будет работать корректно.
     
  13. Igor68

    Igor68 Гуру

    1 - это Ваш код и Вы сами на это не обратили внимание
    2 - это вообще тест, и принципиального значения не имеет... что там размер 64 бита, что там. Важно что бы работали одинаково полностью на разных устройствах.
     
  14. Igor68

    Igor68 Гуру

    Вот это и надо говорить... ведь не сложно, правда?
     
  15. Igor68

    Igor68 Гуру

    Ну пусть будет size_t размерность-то единая.
     
  16. SergeiL

    SergeiL Оракул Модератор

    Так они и будут одинаково работать,
    У Вас по указателю на uint64_t в массив данные прописываются, а тут все к uint8_t приводится, и потом n количество байт копируется.
    С uint64_t могут быть сюрпризы, в виде выравниваний, а с uint8_t - меньше уже не куда, и нечего выравнивать - сюрпризов не будет.
     
  17. b707

    b707 Гуру

    я не про size_t писал, а про unsigned в одном случае и signed в другом.
    Если не обращать на это внимание - можно очень хорошо налететь.
    Если же Вам не важно представление ваших байт в массиве - не нужно их выводить в виде числа через printf
     
    Последнее редактирование: 18 дек 2020
  18. b707

    b707 Гуру

    когда есть моя вина, я это и признаю.
    А не сваливаю на "неправильные компиляторы" :)
     
  19. b707

    b707 Гуру

    без знания языка никакого соответствия не получится
    Третий раз повторяю - трактуйте весь массив как байты - и все всегда будет на одном и том же месте
     
  20. SergeiL

    SergeiL Оракул Модератор

    Не всегда.
    Есть процессоры с разным порядком хранения байт.
    Есть от старшего к младшему а есть - наоборот.
    Когда то стыковались с Cray, весь обмен шел в текстовом виде именно по этой причине.
     
    Последнее редактирование: 18 дек 2020