C Array flessibili: quando sono diventati parte dello standard?

4

Ho imparato a programmare in C molti anni fa e ho usato C regolarmente per circa 10 anni.

In questi giorni, di tanto in tanto devo guardare al codice C, perché i nostri runner personalizzati RDS Informix 4GL contengono anche codice C, ma è un codice piuttosto semplicistico.

Quando usavo molto C, non ricordo di aver mai sentito parlare di array flessibili. Sto facendo questa domanda, perché ho trovato questo SO domanda. Grazie.

    
posta octopusgrabbus 24.06.2012 - 21:21
fonte

3 risposte

5

È definito in ISO C99; Non so davvero se è stato definito prima, ma ne dubito.

Tradizionalmente, le strutture con matrici flessibili ora specificate sono state dichiarate con matrici di dimensione 1 alla fine e quindi assegnate in base alla dimensione desiderata, un trucco noto come " struct hack ". Esempi di questo possono essere visti ad esempio. nell'API di Windows.

    
risposta data 24.06.2012 - 21:29
fonte
8

Ci sono due cose diverse aggiunte dallo standard C99 e sono facili da mescolare per errore:

Membri di array flessibili . Ciò significa che una struttura può avere un membro di dimensioni sconosciute alla fine. Esempio dallo standard C:

struct s { int n; double d[]; };

int m = /* some value */;
struct s *p = malloc(sizeof (struct s) + sizeof (double [m]));

Anche questo era usato prima del C99, ma era quindi un comportamento indefinito, noto come "struct hack" a cui si fa riferimento in un'altra risposta. Prima del C90, potrebbero esserci byte di padding inaspettati alla fine della struct, che portano a bug.

Array di lunghezza variabile (VLA). Questi sono array con le loro dimensioni impostate in runtime. Probabilmente sono implementati dal compilatore usando l'allocazione dinamica della memoria. Esempio:

void func (int n)
{
  int array[n];
}
    
risposta data 26.06.2012 - 13:20
fonte
1

C99 li ha standardizzati. Tuttavia, sono stati usati molto prima con gli array a 1 elemento, un trucco noto come struct hack .

It's not clear if it's legal or portable, but it is rather popular. An implementation of the technique might look something like this:

    #include <stdlib.h>
    #include <string.h>

    struct name *makename(char *newname)
    {
        struct name *ret =
            malloc(sizeof(struct name)-1 + strlen(newname)+1);
                    /* -1 for initial [1]; +1 for %bl0ck_qu0te% */
        if(ret != NULL) {
            ret->namelen = strlen(newname);
            strcpy(ret->namestr, newname);
        }

        return ret;
    }

This function allocates an instance of the name structure with the size adjusted so that the namestr field can hold the requested name (not just one character, as the structure declaration would suggest).

Despite its popularity, the technique is also somewhat notorious: Dennis Ritchie has called it ''unwarranted chumminess with the C implementation,'' and an official interpretation has deemed that it is not strictly conforming with the C Standard, although it does seem to work under all known implementations. (Compilers which check array bounds carefully might issue warnings.)

Another possibility is to declare the variable-size element very large, rather than very small...

    
risposta data 24.06.2012 - 21:29
fonte

Leggi altre domande sui tag