Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the purpose of this [1] at the end of struct declaration?

I was snooping through my MSP430 microcontroller's header files, and I ran into this in <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 */

I understand that it declares an anonymous struct and typedef's it to jmp_buf, but I can't figure out what the [1] is for. I know it declares jmp_buf to be an array with one member (of this anonymous struct), but I can't imagine what it's used for. Any ideas?

like image 418
Alexander Avatar asked Nov 02 '17 23:11

Alexander


People also ask

What is at the end of a struct?

Statement: Defines the field names, types of data within fields, and order and alignment of fields within a record structure. Fields and structures can be initialized, but records cannot be initialized. Is the name used to identify a structure, enclosed by slashes.

Where do you declare structs?

Declaration. The general syntax for a struct declaration in C is: struct tag_name { type member1; type member2; /* declare as many members as desired, but the entire structure size must be known to the compiler.

What is typedef struct in C++?

The C language contains the typedef keyword to allow users to provide alternative names for the primitive (e.g.,​ int) and user-defined​ (e.g struct) data types. Remember, this keyword adds a new name for some existing data type but does not create a new type.

Where should the code for the struct definition be placed?

The structure definition for an ADT should usually be in the source ( . c ) file that defines the support functions, and only a declaration of the type should exist in the header ( .


1 Answers

This is a common trick to make a "reference type" in C, where using it as a function argument causes the single element array to degrade to a pointer to its first element without the programmer needing to explicitly use the & operator to get its address. Where declared, it's a real stack type (no dynamic allocation needed), but when passed as an argument, the called function receives a pointer to it, not a copy, so it's passed cheaply (and can be mutated by the called function if not const).

GMP uses the same trick with its mpz_t type, and it's critical there, because the structure manages a pointer to dynamically allocated memory; the mpz_init function relies on getting a pointer to the structure, not a copy of it, or it couldn't initialize it at all. Similarly, many operations can resize the dynamically allocated memory, and that wouldn't work if they couldn't mutate the caller's struct.

like image 63
ShadowRanger Avatar answered Oct 22 '22 23:10

ShadowRanger