Arduino sizeof struct

maco

Arduino sizeof struct
« kdy: 10. 02. 2018, 22:41:38 »
Neviem si dat rady so strukturov v Arduine (ESP32 v Platformio), potrebujem s nou pracovat ako so smernikom, no sprava sa to neocakavane.


Kód: [Vybrat]
typedef struct pokus_struct {
  unsigned char unsignedchar1;//1 byte
  float float1;          //4 bytes
} Pokus;

Pokus pokus;

  pokus.unsignedchar1=1;         
  pokus.float1=2;

  Serial.println(sizeof(pokus)); // do terminalu to posle 8
  Serial.write((byte*)&pokus, sizeof(pokus)); // 01 00 00 00 00 00 00 40

  Serial.println(sizeof(pokus.unsignedchar1)); // 1
  Serial.write((byte*)&pokus.unsignedchar1, sizeof(pokus.unsignedchar1)); // 01

  Serial.println(sizeof(pokus.float1)); // 4
  Serial.write((byte*)&pokus.float1, sizeof(pokus.float1)); // 00 00 00 40
[/pre]

Ocakaval som ze struktura pokus ma velkost 5 bytov, odkial je tam 8 bytov?
Ked som z nej vyhodil float, tak mala velkost 1 byte, ked som z nej vyhodil unsignedchar, mala velkost 4 byte
Skusal som definovat jej prvky aj cez uint8_t, float_t, vysledok bol podobny.
Vie niekto dat typ co s tym?
« Poslední změna: 11. 02. 2018, 19:39:46 od Petr Krčmář »


monolog

Re:arduino sizeof struct
« Odpověď #1 kdy: 10. 02. 2018, 23:06:17 »
Prekladac pridal 3 byty medzi char a float kvoli zarovnaniu. Rozne arch. maju rozne naroky na zarovanie, je obvykle ze viacbytove datove typy musia zacinat na adresach delitelnych svojou velkostou. Vysledna velkost by sa mala zmensit pri prehodeni poradia, alebo pouziti __attribute__((packed)).

Jenda

Re:arduino sizeof struct
« Odpověď #2 kdy: 10. 02. 2018, 23:06:35 »
structure padding

attribute packed

Přímý přístup k prvku nezarovnané struktury by měl kompilátor odchytit a vyřešit, ale pokud na něj vlezeš pointrem, tak na to nemusí přijít a na některých architekturách (nižší ARMy) se stanou divné věci (např. se pointer tiše zaokrouhlí) a na jiných (x86 se SSE) se vyhodí výjimka. ESP32 neznám.

maco

Re:arduino sizeof struct
« Odpověď #3 kdy: 10. 02. 2018, 23:33:44 »
Dakujem, vyriesene. Pomohlo usporiadat premenne aby boli po nasobkoch 4, tiez pomohlo aj packed..

typedef struct __attribute__((packed)) pokus_struct {
  unsigned char unsignedchar1;//1 byte
  float float1;          //4 bytes
} Pokus;

borekz

  • ****
  • 486
    • Zobrazit profil
    • E-mail
Re:arduino sizeof struct
« Odpověď #4 kdy: 11. 02. 2018, 08:33:50 »
Myslel jsem, že procesory ARM bez alignu nefungují.


Trupik

Re:arduino sizeof struct
« Odpověď #5 kdy: 11. 02. 2018, 10:30:06 »
Myslel jsem, že procesory ARM bez alignu nefungují.
Bohvie čo z toho prekladač na pozadí vygeneroval. Je možné, že každá operácia nad tým nezarovnaným floatom bude odteraz desaťkrát pomalšia než predtým, pretože okolo nej budú ešte inštrukcie na správne poskladanie po načítaní a spätný rozklad pre uloženie.

...
Ak ide len o šetrenie bajtov, tak k tomu by som povedal toľko:

1.) Buď tam v celom programe tá štruktúra bude "napevno" len pár-krát a potom jej veľkosť nemá cenu riešiť.

2.) Alebo bude alokovaná dynamicky a bude v pamäti zaberať nejakú mocninu dvojky. Pokiaľ si dobre pamätám, na 64-bitovom stroji volanie malloc(5) v skutočnosti alokuje a vráti 32 bajtov.

3.) Alebo štruktúra bude v poli a potom aj tak každý jej výskyt bude zarovnaný na osem bajtov, aj keď sa Ti samotnú štruktúru podarí spakovať na päť.

Samozrejme, má zmysel vedieť, čo sa vnútri deje, aby si vedel správne štruktúru usporiadať. Mať ako prvý prvok char[1] a za ním niečo iné ako char je naozaj zlý dizajn.

Jenda

Re:arduino sizeof struct
« Odpověď #6 kdy: 11. 02. 2018, 10:42:20 »
Myslel jsem, že procesory ARM bez alignu nefungují.

Některé vyšší ARMy ho podporují, nižší ne. https://medium.com/@iLevex/the-curious-case-of-unaligned-access-on-arm-5dd0ebe24965

Nejhorší je, když to tiše selže. To se mi samozřejmě stalo a pak jsem si tiskl dumpy na papír a kreslil si v tom pastelkama než jsem na to přišel.

3.) Alebo štruktúra bude v poli a potom aj tak každý jej výskyt bude zarovnaný na osem bajtov, aj keď sa Ti samotnú štruktúru podarí spakovať na päť.

To se mi nezdá (gcc7.3 na amd64):
Kód: [Vybrat]
/tmp> cat pokus.c
#include <nsautil.h>

typedef struct __attribute__((packed)) pokus_struct {
  unsigned char unsignedchar1;//1 byte
  float float1;          //4 bytes
} Pokus;

Pokus p[100];

int main(int argc, char **argv) {
  for(int i=0; i<4; i++) {
    printf("size: %zu, addr: %p\n", sizeof(Pokus), &p[i]);
  }
}

/tmp> jcc pokus.c
/tmp> ./pokus
size: 5, addr: 0x556b9e257140
size: 5, addr: 0x556b9e257145
size: 5, addr: 0x556b9e25714a
size: 5, addr: 0x556b9e25714f

Trupik

Re:arduino sizeof struct
« Odpověď #7 kdy: 11. 02. 2018, 19:12:47 »
...
3.) Alebo štruktúra bude v poli a potom aj tak každý jej výskyt bude zarovnaný na osem bajtov, aj keď sa Ti samotnú štruktúru podarí spakovať na päť.

To se mi nezdá (gcc7.3 na amd64):
Kód: [Vybrat]
/tmp> cat pokus.c
#include <nsautil.h>

typedef struct __attribute__((packed)) pokus_struct {
  unsigned char unsignedchar1;//1 byte
  float float1;          //4 bytes
} Pokus;

Pokus p[100];

int main(int argc, char **argv) {
  for(int i=0; i<4; i++) {
    printf("size: %zu, addr: %p\n", sizeof(Pokus), &p[i]);
  }
}

/tmp> jcc pokus.c
/tmp> ./pokus
size: 5, addr: 0x556b9e257140
size: 5, addr: 0x556b9e257145
size: 5, addr: 0x556b9e25714a
size: 5, addr: 0x556b9e25714f
Zaujímavé. Človek sa zjavne stále má čo učiť.  :)

ehmmm

Re:arduino sizeof struct
« Odpověď #8 kdy: 11. 02. 2018, 20:01:12 »
Bohvie čo z toho prekladač na pozadí vygeneroval. Je možné, že každá operácia nad tým nezarovnaným floatom bude odteraz desaťkrát pomalšia než predtým, pretože okolo nej budú ešte inštrukcie na správne poskladanie po načítaní a spätný rozklad pre uloženie.

Kdyz jsem si hral vloni v zime s Arduinem s ATmegou, tak se dal ten HEX, co se nalejva, zase disassemblovat.
(Tenkrat se mi udelalo trochu nevolno pri pohledu na velmi oblibenou funkci digitalWrite(), ale pak jsem se s tim nejak smiril.)