ISO C equivalente de grupos arriostrados dentro de expresiones
Pregunta
¿Cómo puedo hacer lo siguiente de manera compatible (ISO C99)?
#define MALLOC(type, length, message) ({ \
type * a_##__LINE__ = (type *)malloc((length) * sizeof(type)); \
assert(message && (a_##__LINE__ != NULL)); \
a_##__LINE__; \
})
double **matrix = MALLOC(double *, height, "Failed to reserve");
NB: para compilar uso: gcc -std = c99 -pedantic ...
Solución
No debe poner la prueba para malloc ()
en un afirmar ()
: no se compilará cuando realice una compilación de lanzamiento. No he usado afirmar ()
en el siguiente programa.
#include <stdio.h>
#include <stdlib.h>
void *mymalloc(size_t siz, size_t length,
const char *message, const char *f, int l) {
void *x = malloc(siz * length);
if (x == NULL) {
fprintf(stderr, "a.out: %s:%d: MALLOC: "
"Assertion `\"%s\" && x != ((void *)0)' failed.\n",
f, l, message);
fprintf(stderr, "Aborted\n");
exit(EXIT_FAILURE);
}
return x;
}
#define MALLOC(type, length, message)\
mymalloc(sizeof (type), length, message, __FILE__, __LINE__);
int main(void) {
int height = 100;
double **matrix = MALLOC(double *, height, "Failed to reserve");
/* work; */
free(matrix);
return 0;
}
Otros consejos
No existe un equivalente estándar para la extensión GCC que está utilizando.
Puede lograr el resultado equivalente usando una función (posiblemente incluso una función en línea si está usando C99) en lugar del código en la macro. Todavía necesita una macro para invocar esa función porque uno de los argumentos es un 'nombre de tipo' y no puede pasarlos a las funciones.
Vea la respuesta de @pmg para obtener una ilustración del tipo de función y macro que la usa.