Я просматривал файлы заголовков своего микроконтроллера 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
массивом с одним членом (этой анонимной структуры), но я не могу представить, для чего он используется. Любые идеи?
c
struct
reverse-engineering
declaration
typedef
Александр - Восстановить Монику
источник
источник
Ответы:
Это распространенный трюк для создания «ссылочного типа» в C, где использование его в качестве аргумента функции приводит к тому, что массив с одним элементом превращается в указатель на его первый элемент, и программисту не нужно явно использовать
&
оператор для получения его адреса. Если объявлен, это настоящий тип стека (динамическое выделение не требуется), но при передаче в качестве аргумента вызываемая функция получает указатель на нее, а не копию, поэтому она передается дешево (и может быть изменена вызываемой функцией, если неconst
).GMP использует тот же трюк со своим
mpz_t
типом, и здесь это очень важно, потому что структура управляет указателем на динамически выделяемую память;mpz_init
функция рассчитывает получить указатель на структуру, а не его копию, или он не может инициализировать его вообще. Точно так же многие операции могут изменять размер динамически выделяемой памяти, и это не сработало бы, если бы они не могли изменить структуру вызывающей стороны.источник
=
.typedef
вот такого. Да, делать это специальным образом было бы ужасно, но если у вас есть слегка непрозрачный тип, когда пользователю API никогда не нужно думать о семантике ссылки и не ссылочной (она всегда должна передаваться по ссылке), это разумный способ о добавлении семантики автоматической ссылки к языку, в котором она отсутствует. Он работает даже в том случае, если пользователь пишет свои собственные API-интерфейсы, которые получают тип, потому что в C объявление о том, что вы принимаете массив в качестве аргумента, действительно означает, что вы принимаете указатель; все "просто работает".... otherwise lacks it
вот что в нем мерзости . Ограничения C, а не сам обходной путь*
в коде.