Dado que usted lo pidió;) hay una herramienta en C para evitar la duplicación explícita de código, macros. Dicho esto, no veo una manera de no repetir al menos el nombre del tipo. Pero en C++ no pueden tampoco, por lo que C es al menos tan bueno :)
El más fácil de lo que veo es
#define DESIGNATE_NEW(T) \
memcpy(malloc(sizeof(T)), \
&(T const){ __VA_ARGS__ }, \
sizeof(T))
que daría
Type *t = DESIGNATE_NEW(Type,
.a = 2,
.b = 3,
.c = 5,
);
esto tiene varias ventajas.
- inicializa todos los miembros correctamente, incluso en arquitecturas con representaciones no estándar de la
0
para los tipos de flotador o punteros.
- Aparte de la versión de Keith, es aceptable el "estilo de codificación", ya que es solo una expresión que se parece a una inicialización y cualquiera debe capturar de forma visual lo que se supone que debe hacer el segundo snipset de código.
NB: Observar la const
en la macro, esto permite que varias instancias del compuesto literal a ser doblados, si el compilador decide que esto sea relevante. También hay medios para tener una variante donde la lista de designadores es opcional, ver P99 a continuación.
La desventaja es el memcpy
y estaría más feliz con una tarea. En segundo lugar, no hay verificación de falla del malloc
antes de usar el resultado, pero uno podría encontrar algunas rarezas para que el código salga bien.
En P99 voy un poco diferente. No siempre tenemos una función de inicialización para un tipo, algo así como
inline
Type* Type_init(Type* t, int a, int b, int c) {
if (t) {
*t = (Type const){ .a = a, .b = b, .c = c };
}
return t;
}
la que por arte de magia macro se puede hacer para proporcionar argumentos predeterminados para a
, b
c
y si se omiten.Luego puede simplemente usar algo como
Type *t = P99_NEW(Type, 1, 2, 3);
en el código de la aplicación. Esto es mejor, ya que evita la desactivación del puntero cuando falló la llamada a malloc
. Por otro lado, esto reintroduce un orden para los inicializadores, por lo que tampoco es perfecto.
Si pudiera, ¿qué pasaría si 'malloc' devolviera' NULL'? – detly
Parece que realmente quieres C++. –
Pregunta interesante, pero no creo que haya una buena respuesta. Personalmente, simplemente usaría 'calloc' seguido de' t-> a = 2; t-> b = 3; '... (' calloc' está ahí en caso de que quiera omitir miembros, por lo que si sabe que los configurará explícitamente, también podría usar 'malloc') –