Какова цель этого [1] в конце объявления структуры?
Я просматривал заголовочные файлы моего микроконтроллера MSP430, и я столкнулся с этим в <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 */
Я понимаю, что он объявляет анонимную структуру и typedef это jmp_buf
, но я не могу понять, какого [1]
- это для. Я знаю, что он объявляет jmp_buf
чтобы быть массивом с одним членом (этой анонимной структуры), но я не могу себе представить, для чего он используется. Есть идеи?
1 ответ:
Это распространенный трюк, чтобы сделать "ссылочный тип" в C, где использование его в качестве аргумента функции приводит к тому, что массив одного элемента деградирует до указателя на его первый элемент без необходимости явного использования программистом
&
оператора, чтобы получить его адрес. Где объявлено, это реальный тип стека (не требуется динамическое выделение), но при передаче в качестве аргумента вызываемая функция получает указатель на него, а не копию, поэтому она передается дешево (и может быть изменена вызываемой функцией если нетconst
).GMP использует тот же трюк с его
mpz_t
тип, и это очень важно, потому что структура управляет указателем на динамически выделенную память;mpz_init
функция полагается на получение указателя на структуру, а не ее копию, или она вообще не может ее инициализировать. Точно так же многие операции могут изменять размер динамически выделенной памяти, и это не сработает, если они не смогут мутировать структуру вызывающего объекта.