Estaba husmeando en los archivos de encabezado de mi microcontrolador MSP430 y me encontré con esto en <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 */
Entiendo que declara una estructura anónima y typedef jmp_buf
, pero no puedo entender para qué [1]
sirve. Sé que declara jmp_buf
ser una matriz con un miembro (de esta estructura anónima), pero no puedo imaginar para qué se usa. ¿Algunas ideas?
c
struct
reverse-engineering
declaration
typedef
Alexander - Reincorporar a Monica
fuente
fuente
Respuestas:
Este es un truco común para hacer un "tipo de referencia" en C, donde usarlo como un argumento de función hace que la matriz de un solo elemento se degrade a un puntero a su primer elemento sin que el programador necesite usar explícitamente el
&
operador para obtener su dirección. Donde se declara, es un tipo de pila real (no se necesita asignación dinámica), pero cuando se pasa como un argumento, la función llamada recibe un puntero, no una copia, por lo que se pasa de forma económica (y puede ser mutada por la función llamada si noconst
).GMP usa el mismo truco con su
mpz_t
tipo, y es crítico allí, porque la estructura administra un puntero a la memoria asignada dinámicamente; lampz_init
función se basa en obtener un puntero a la estructura, no una copia de ella, o no podría inicializarla en absoluto. De manera similar, muchas operaciones pueden cambiar el tamaño de la memoria asignada dinámicamente, y eso no funcionaría si no pudieran mutar la estructura del llamador.fuente
=
.typedef
como este. Sí, hacer esto ad-hoc sería un poco terrible, pero si tiene un tipo ligeramente opaco, donde el usuario de la API nunca necesita pensar en la semántica de referencia frente a la no referencia ( siempre debe pasar por referencia), es una forma razonable de agregar semántica de referencia automática a un lenguaje que de otra manera carece de ella. Incluso funciona si el usuario escribe sus propias API que reciben el tipo, porque en C, declarar que acepta una matriz como argumento realmente significa que acepta un puntero; todo "simplemente funciona".... otherwise lacks it
es lo más asqueroso. Las limitaciones de C, no la solución en sí misma*
en el código.