2017-11-02 170 views
86

byłem podsłuchiwanie poprzez pliki nagłówka mojego MSP430 mikrokontrolera, i wpadłem na to w <setjmp.h>:Jaki jest cel tego [1] na końcu deklaracji struct?

/* 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 anonimowy struct i typedef to go jmp_buf, ale nie mogę dowiedzieć się, co [1] jest dla. Wiem, że deklaruje ona, że ​​jmp_buf jest tablicą z jednym członkiem (tej anonimowej struktury), ale nie mogę sobie wyobrazić, do czego służy. Jakieś pomysły?

+5

Coś wspólnego z rozkładaniem się na wskaźnik? – Elazar

+3

Ostateczny komentarz wydaje się całkowicie błędny ... –

+0

Doskonałe pytanie! – SRG

Odpowiedz

103

Jest to typowa sztuczka polegająca na utworzeniu "typu odniesienia" w C, gdzie użycie go jako argumentu funkcji powoduje degradację tablicy pojedynczego elementu do wskaźnika do pierwszego elementu bez konieczności użycia przez operatora programatora operatora & aby uzyskać jego adres. Tam, gdzie został zadeklarowany, jest to prawdziwy typ stosu (bez potrzeby alokacji dynamicznej), ale gdy jest przekazywany jako argument, wywoływana funkcja otrzymuje wskaźnik do niego, a nie kopię, więc jest przekazywana tanio (i może być zmutowana przez wywołaną funkcję, jeśli nie const).

GMP używa tej samej sztuczki z typem mpz_t i jest tam krytyczna, ponieważ struktura zarządza wskaźnikiem dynamicznie przydzielanej pamięci; funkcja mpz_init polega na uzyskaniu wskaźnika do struktury, a nie jej kopii lub w ogóle nie mogła go zainicjować. Podobnie, wiele operacji może zmienić rozmiar dynamicznie przydzielanej pamięci, a to nie zadziała, jeśli nie będą mogły zmutować struktury wywołującej.

+12

Zapobiega również kopiowaniu za pomocą '='. – melpomene

+11

To jest brutto. Przyjmuję tę odpowiedź, gdy upłynie min. Czas. Dzięki za pomoc! – Alexander

+2

@Alexander: To nie jest takie obrzydliwe, gdy jest hermetyzowane przez 'typedef' w ten sposób. Tak, zrobienie tego ad-hoc byłoby trochę straszne, ale jeśli masz lekko nieprzejrzysty typ, w którym użytkownik API nigdy nie musi myśleć o odwołaniach a semantyką niereferencyjną (powinien * zawsze * przekazywać przez odniesienie), jest to rozsądny sposób dodawania automatycznej semantyki odniesienia do języka, który w przeciwnym razie nie jest dostępny. Działa nawet wtedy, gdy użytkownik pisze własne API, które otrzymuje typ, ponieważ w C deklaracja przyjęcia tablicy jako argumentu oznacza, że ​​akceptujesz wskaźnik; wszystko "po prostu działa". – ShadowRanger