Какова цель этого [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 89

1 ответ:

Это распространенный трюк, чтобы сделать "ссылочный тип" в C, где использование его в качестве аргумента функции приводит к тому, что массив одного элемента деградирует до указателя на его первый элемент без необходимости явного использования программистом & оператора, чтобы получить его адрес. Где объявлено, это реальный тип стека (не требуется динамическое выделение), но при передаче в качестве аргумента вызываемая функция получает указатель на него, а не копию, поэтому она передается дешево (и может быть изменена вызываемой функцией если нет const).

GMP использует тот же трюк с его mpz_t тип, и это очень важно, потому что структура управляет указателем на динамически выделенную память;mpz_init функция полагается на получение указателя на структуру, а не ее копию, или она вообще не может ее инициализировать. Точно так же многие операции могут изменять размер динамически выделенной памяти, и это не сработает, если они не смогут мутировать структуру вызывающего объекта.