Miembro de la unión y tamaño de la matriz de caracteres en c

0

Hace años tuve una buena experiencia de trabajo en C. Ahora está oxidado. No se puede encontrar la forma correcta de crear una unión con 2 elementos

typedef struct {
// multiple elements
}SETTINGS;

 typedef union{
       SETTINGS PROC;
       unsigned char BYTES[sizeof PROC];
 }PROCESS_SETTINGS;

¿Quiero usar sizeof aquí pero no encuentro cómo? sizeof PROC informa de un error.

    
pregunta Decapod

3 respuestas

5

El estándar C dice:

  

El operador sizeof produce el tamaño (en bytes) de su operando, que puede ser una expresión o el nombre entre paréntesis de un tipo.

PROC no es una expresión (que requeriría pasar por un objeto del tipo de unión primero, por ejemplo, sizeof(u->PROC) ), por lo que debe usar el tipo en su lugar. Y con un tipo, debes usar paréntesis:

typedef union {
    SETTINGS PROC;
    unsigned char BYTES[sizeof(SETTINGS)];
} PROCESS_SETTINGS;
    
respondido por el CL.
4

Hay un lenguaje extraño (pero útil) en C que se encuentra a menudo. Y puede que te resulte útil aquí.

typedef union {
    short int x;
    float y;
    unsigned char z[1];
} MyUnion;

int main( int argc, char *argv[] ) {
    MyUnion s;
    s.x = 1000;
    printf("%u %u %u\n", sizeof(MyUnion), s.z[0], s.z[1]);
    return 0;
}

Tenga en cuenta que ni siquiera necesita especificar la extensión real de z []. Ajustarlo a uno cumple con el estándar moderno de sintaxis. Superar el límite de cualquier matriz en tiempo de ejecución es un comportamiento indefinido, pero por lo tanto usaremos una matriz para indexar a través de cualquier declaración, ya que los problemas de relleno y alineación dependen del objetivo, de todos modos.

El uso de índices fuera del límite dado se encuentra en el código del compilador c, las bibliotecas (malloc, por ejemplo, a menudo usa [-1] como un índice de matriz), sistemas operativos y otros. Es bastante común, por ejemplo, encontrar en el uso de:

typedef struct {
    int typecode;
    int len;
    char s[1];
} packet_t;

para paquetes de red, registros de archivos de objetos, etc. La asignación real se realiza a través de malloc, sin embargo, para garantizar que exista el tamaño adecuado. No está mal y se hace a menudo.

Ya que es parte de una unión, comenzará desde el principio. Pero el tamaño de la unión será determinado por el elemento más grande y no por él.

C requiere que cualquier objeto tenga una dirección única. Entonces, si la unión no tiene otras definiciones dentro de ella, la creación de una instancia del objeto requerirá espacio. Pero esto es simplemente para cumplir con el requisito de que diferentes instancias tengan direcciones diferentes.

Si simplemente estuviera tratando de crear una matriz de bytes que asigne una unión de objeto (s), definitivamente NO me molestaría en absoluto con un operador sizeof (). Simplemente lo escribiría como lo hice arriba. Guarda texto y guarda el riesgo de tener que editar esa línea si cambio el nombre de algo.

    
respondido por el jonk
3

TL; DR: siempre usa paréntesis después de sizeof y funcionará.

Esto se debe a la sintaxis peculiar del operador sizeof , C11 6.5.3:

  

6.5.3 Operadores Unarios
  Sintaxis
  / - /
sizeof unary-expression
sizeof (nombre-tipo)

Como podemos ver, se presenta en dos formas, una forma que se puede usar para expresiones de tiempo de compilación y no necesita paréntesis, y otra forma que se puede usar para tipos, que sí la necesitan.

Significado:

sizeof 1;     // ok, it's an expression
sizeof int;   // syntax error, it's a type
sizeof (int); // ok

Ahora, como se ve, cualquier expresión puede contener un paréntesis, que es un operador con la mayor prioridad:

sizeof (1);   // ok, here the parenthesis is an operator of its own not part of sizeof
sizeof (int); // ok, here the parenthesis is part of the sizeof operator syntax

Entonces, siempre se puede escribir un paréntesis después de sizeof y cubrirá ambos casos.

    
respondido por el Lundin

Lea otras preguntas en las etiquetas