J'étais en train de fouiner dans les fichiers d'en-tête de mon microcontrôleur MSP430, et je suis tombé sur ceci dans <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 */
Je comprends qu'il déclare une structure anonyme et qu'il est typedef jmp_buf
, mais je ne peux pas comprendre à quoi cela [1]
sert. Je sais qu'il déclare jmp_buf
être un tableau avec un membre (de cette structure anonyme), mais je ne peux pas imaginer à quoi il sert. Des idées?
c
struct
reverse-engineering
declaration
typedef
Alexander - Réintégrer Monica
la source
la source
Réponses:
C'est une astuce courante pour créer un "type de référence" en C, où son utilisation comme argument de fonction provoque la dégradation du tableau d'élément unique en un pointeur vers son premier élément sans que le programmeur ait besoin d'utiliser explicitement l'
&
opérateur pour obtenir son adresse. Lorsqu'elle est déclarée, c'est un vrai type de pile (aucune allocation dynamique nécessaire), mais lorsqu'elle est passée en argument, la fonction appelée reçoit un pointeur vers elle, pas une copie, donc elle est passée à bas prix (et peut être mutée par la fonction appelée sinonconst
).GMP utilise la même astuce avec son
mpz_t
type, et c'est critique là-bas, car la structure gère un pointeur vers la mémoire allouée dynamiquement; lampz_init
fonction repose sur l'obtention d'un pointeur vers la structure, pas une copie de celle-ci, ou elle n'a pas pu l'initialiser du tout. De même, de nombreuses opérations peuvent redimensionner la mémoire allouée dynamiquement, et cela ne fonctionnerait pas si elles ne pouvaient pas muter la structure de l'appelant.la source
=
.typedef
comme ça. Ouais, faire cela ad-hoc serait un peu terrible, mais si vous avez un type légèrement opaque, où l'utilisateur de l'API n'a jamais besoin de penser à la sémantique de référence par rapport à la sémantique sans référence (cela devrait toujours passer par référence), c'est un moyen raisonnable d'ajouter une sémantique de référence automatique à un langage qui en manque autrement. Cela fonctionne même si l'utilisateur écrit ses propres API qui reçoivent le type, car en C, déclarer que vous acceptez un tableau comme argument signifie vraiment que vous acceptez un pointeur; tout "fonctionne juste".... otherwise lacks it
c'est ce qui est dégoûtant. Les limites de C, pas la solution de contournement elle*
dans le code.