Rozmiar typu uint8_t i rozmiar wskaźników w C na uC.

0

Cześć,
Kilka razy już słyszałem, że typ uint8_t, uint16_t zajmuje 32bity na proceorach 32 bitowych, konkretnie dotyczyło to mikrokontrolerów 32 bitowych.
Napisałem mały program który to sprawdza:

  uint8_t *a;
  uint32_t *b;
  double *c;

  UART_printf("sizeof(uint8_t*) = %d\r\n", sizeof(a));
  UART_printf("sizeof(uint32_t*) = %d\r\n", sizeof(b));
  UART_printf("sizeof(double*) = %d\r\n", sizeof(c));

  uint8_t val1;
  uint8_t val2;
  uint8_t val3;
  uint8_t val4;

  UART_printf("Address of val1 = %x\r\n", &val1);
  UART_printf("Address of val2 = %x\r\n", &val2);
  UART_printf("Address of val3 = %x\r\n", &val3);
  UART_printf("Address of val4= %x\r\n", &val4);

i taki jest wynik tego programu na procesorze ARM M4

sizeof(uint8_t*) = 4                                          
sizeof(uint32_t*) = 4                                         
sizeof(double*) = 4
                                                           
Address of val1 = 20001fef            
Address of val2 = 20001fee                
Address of val3 = 20001fed                                  
Address of val4 = 20001fec

Z tego można wywnioskować że typ uint8_t zajmuje dokładnie tyle ile powinien -> 1bajt. Jak to będzie wyglądało na innych systemach?
Druga kwestia to rozmiar wskaźnika. Na Cortexie M4 wskaźnik na uint8_t uint32_t i double zajmuje tyle ile długość słowa, czyli 32 bity. Od czego to zależy?
Od długości słowa, kompilatora?

2

To w końcu sprawdzasz typy liczbowe czy wskaźniki?

2

Sizeof pointera do dowolnego typu zmiennej zajmuje tyle co void*

2

http://en.cppreference.com/w/cpp/types/integer
Typy formatu uint8_t, zawierają tyle bitów ile opisują dokładnie. Typy z least w nazwie, najmniej tyle bitów. Typy z nazwą fast, mają zawierać najmniej tyle bitów na ile wskazywać, ale mają być szybkie na danej platformie.

3

Rozmiar wskaźnika zależy od platformy - architektury procesora, modelu pamięci.

uint8_t ma gwarantowany rozmiar 8 bitów, uint16_t - 16, uint32_t - zgadnij.

Craith napisał(a):

Sizeof pointera do dowolnego typu zmiennej zajmuje tyle co void*

Nie musi być to prawdą na architekturach rozróżniających wskaźniki bliskie i dalekie (near i far).
Poza tym nie ma gwarancji że rozmiar wskaźnika na kod (wskaźnik na funkcję) będzie równy rozmiarowi wskaźnika na dane.

2
Craith napisał(a):

Nie mówię że nie masz racji, ale czy potrafisz podać przykład do near/far pointerów oraz różnicy w rozmiarach pointerów do funkcji oraz danych?

Wskaźniki bliskie i dalekie były w architekturach 16-bitowych. Zależnie od przyjętego modelu pamięci, kod może być „bliski” (wskaźnik ma 2 bajty) a dane „dalekie” (4 B), albo odwrotnie, albo 2-2, albo 4-4.
Ale nie trzeba się uciekać do starych czy egzotycznych architektur, by zauważyć że nie wszystkie wskaźniki mają tę samą wielkość.
Pod C++ (bo raczej nie C) wskaźnik na metodę wirtualną może mieć rozmiar większy niż void* (a więc jeden wskaźnik na kod może mieć inny rozmiar niż inny wskaźnik na kod). Podawałem na tym forum kiedyś przykład, wraz z porównaniem różnego zachowania GCC i Visual C++ na tym samym systemie.

0

Zupełnie nie wiem co pewni ludzie mieli na myśli że nie warto stosować typów uint8_t, int8_t, uint16_t, int16_t na ARM Cortex M4.

0
Nadziany Polityk napisał(a):

Zupełnie nie wiem co pewni ludzie mieli na myśli że nie warto stosować typów uint8_t, int8_t, uint16_t, int16_t na ARM Cortex M4.

chodzi o odczyt z niewyrównanych adresów... Tam będzie błędny, albo bardzo wolny.

0
kaczus napisał(a):
Nadziany Polityk napisał(a):

Zupełnie nie wiem co pewni ludzie mieli na myśli że nie warto stosować typów uint8_t, int8_t, uint16_t, int16_t na ARM Cortex M4.

chodzi o odczyt z niewyrównanych adresów... Tam będzie błędny, albo bardzo wolny.
W jaki sposób błędny? W moim przykładzie wartości val1, val2, val3 są ulokowane na nierównych adresach, i jakoś błędów przy odczycie i zapisie nie zauważyłem.

0

a słyszałeś o takich co potrafią rzutować i próbują coś uzyskać w ten sposób:

uint8_t x = *((uint8_t *)(dane + 5))

A potem zdziwienie, że coś nie działa....

0
Nadziany Polityk napisał(a):

Zupełnie nie wiem co pewni ludzie mieli na myśli że nie warto stosować typów uint8_t, int8_t, uint16_t, int16_t na ARM Cortex M4.

struct TestA {
     int8_t a;
     int32_t, b;
};

sizeof(TestA) ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1