Szperałem w plikach nagłówkowych mojego mikrokontrolera MSP430 i natknąłem się na to w <setjmp.h>
:
/* r3 does not have to be saved */
typedef struct
{
uint32_t __j_pc; /* return address */
uint32_t __j_sp; /* r1 stack pointer */
uint32_t __j_sr; /* r2 status register */
uint32_t __j_r4;
uint32_t __j_r5;
uint32_t __j_r6;
uint32_t __j_r7;
uint32_t __j_r8;
uint32_t __j_r9;
uint32_t __j_r10;
uint32_t __j_r11;
} jmp_buf[1]; /* size = 20 bytes */
Rozumiem, że deklaruje anonimową strukturę i jest to typedef jmp_buf
, ale nie mogę dowiedzieć się, do czego [1]
służy. Wiem, że deklaruje, jmp_buf
że jest tablicą z jednym elementem (tej anonimowej struktury), ale nie mogę sobie wyobrazić, do czego służy. Jakieś pomysły?
c
struct
reverse-engineering
declaration
typedef
Alexander - Przywróć Monikę
źródło
źródło
Odpowiedzi:
Jest to powszechna sztuczka przy tworzeniu „typu referencyjnego” w C, gdzie użycie go jako argumentu funkcji powoduje degradację tablicy jednoelementowej do wskaźnika do jej pierwszego elementu bez konieczności jawnego użycia
&
operatora w celu uzyskania jej adresu. Tam, gdzie jest zadeklarowany, jest to prawdziwy typ stosu (nie jest wymagana alokacja dynamiczna), ale gdy jest przekazywana jako argument, wywoływana funkcja otrzymuje wskaźnik do niej, a nie kopię, więc jest przekazywana tanio (i może zostać zmutowana przez wywołaną funkcję, jeśli nieconst
).GMP używa tej samej sztuczki ze swoim
mpz_t
typem i jest tam krytyczny, ponieważ struktura zarządza wskaźnikiem do dynamicznie przydzielanej pamięci;mpz_init
funkcja polega na uzyskiwanie wskaźnik do struktury, a nie kopia, lub nie może zainicjować go w ogóle. Podobnie, wiele operacji może zmienić rozmiar dynamicznie przydzielonej pamięci, a to nie zadziałałoby, gdyby nie mogły zmutować struktury wywołującego.źródło
=
.typedef
taki sposób. Tak, zrobienie tego ad-hoc byłoby trochę okropne, ale jeśli masz lekko nieprzejrzysty typ, w którym użytkownik API nigdy nie musi myśleć o semantyce referencyjnej w porównaniu do semantyki bez referencji ( zawsze powinna być przekazywana przez referencję), jest to rozsądny sposób dodawania automatycznej semantyki odwołań do języka, który w innym przypadku jej nie ma. Działa nawet, jeśli użytkownik napisze własne API, które otrzymają typ, ponieważ w C deklaracja, że akceptujesz tablicę jako argument, w rzeczywistości oznacza, że akceptujesz wskaźnik; wszystko „po prostu działa”.... otherwise lacks it
jest w niej obrzydliwa. Ograniczenia C, a nie samo obejście*
w kodzie.