Presioné un código c en el kernel de Linux:
static struct ctl_table ip_ct_sysctl_table[] = { { .procname = "ip_conntrack_max", .maxlen = sizeof(int), .mode = 0644, .proc_handler = proc_dointvec, }, // ... { .procname = "ip_conntrack_log_invalid", .maxlen = sizeof(unsigned int), .mode = 0644, .proc_handler = proc_dointvec_minmax, .extra1 = &log_invalid_proto_min, .extra2 = &log_invalid_proto_max, }, { } }; Aquí una matriz de estructuras termina con { } . ¿Con qué propósito se agregó?
Por cierto, un poco más arriba de este código hay otra matriz de estructuras , pero sin llaves vacías al final.
¿Cuándo debo usar llaves vacías al final de una matriz de estructuras?
Probablemente esté familiarizado con las cadenas terminadas en cero. ctl_table ip_ct_sysctl_table[] es una matriz terminada en cero, es decir, la última entrada de la matriz tiene todos los miembros cero.
Es un elemento inicializado en cero al final de la matriz para aumentar la cantidad de elementos de la matriz en uno.
Considere esta pequeña demostración:
#include <stdio.h> struct Test { int x; int y; } arr[] = { {1,2}, {3,4}, // {} }; int main(void) { printf("%zu\n", sizeof(arr) / sizeof(arr[0])); return 0; } El tamaño de la matriz arr cambiará si quita el comentario de {} al final de la lista de inicialización de la matriz.
Salidas:
Con // {} (el arreglo tiene 2 elementos)
2 Con {} (el arreglo tiene 3 elementos)
3Explicación adicional:
La matriz ip_ct_sysctl_table solo se usa en un lugar, aquí:
in->ctl_table = kmemdup(ip_ct_sysctl_table, sizeof(ip_ct_sysctl_table), GFP_KERNEL); El {} extra aumenta el tamaño total ip_ct_sysctl_table .
Este cambio en particular fue parte de la red sysctl: elimine la confirmación del código sysctl binario no utilizado por parte de Eric W. Biederman, cambiando la inicialización del último elemento de la matriz ip_ct_sysctl_table de {0} a {} (y realiza cambios similares a muchas otras inicializaciones de matriz ).
Sin embargo, el patrón {0} parece haber existido durante mucho más tiempo, y la inicialización del elemento final {0} o {} se suele denominar explícitamente (en el código fuente de Linux) como Terminating entry , por lo que es probable que esté presente un patrón para permitir el consumo de estas matrices sin conocer sus longitudes, terminando el consumo al presionar la entrada de terminación inicializada en cero. Por ejemplo, para las matrices similares en sound/aoa/fabrics/snd-aoa-fabric-layout.c la intención de la inicialización cero incluso se menciona explícitamente en un comentario, por ejemplo:
static struct codec_connection toonie_connections[] = { { .connected = CC_SPEAKERS | CC_HEADPHONE, .codec_bit = 0, }, {} /* terminate array by .connected == 0 */ };
¿Cuál es la necesidad de llaves vacías '{ }' al final de la matriz de estructuras?
Para ser claros: las "llaves vacías '{ }' al final de la matriz de estructuras" no son necesarias para satisfacer los requisitos de sintaxis de C.
¿Cuándo debo usar llaves vacías al final de una matriz de estructuras?
Cuando el código quiere un valor centinela .
A veces es útil que el programa tenga un elemento de matriz final de todos ceros, ciertamente para detectar el final. La necesidad proviene del uso que hace la aplicación de la matriz ctl_table ip_ct_sysctl_table[] , no de una necesidad del lenguaje C.