ISO C equivalent of braced-groups within expressions
How can I do the following in a compliant (ISO C99) way?
#define MALLOC(type, length, message) ({ \
type * a_##__LINE__ = (type *)malloc((length) * sizeo开发者_运维技巧f(type)); \
assert(message && (a_##__LINE__ != NULL)); \
a_##__LINE__; \
})
double **matrix = MALLOC(double *, height, "Failed to reserve");
NB: to compile I use: gcc -std=c99 -pedantic ...
You shouldn't put the test for malloc()
in an assert()
: it won't be compiled in when you do a release build. I haven't used assert()
in the following program.
#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;
}
There is no standard equivalent to the GCC extension you are using.
You can achieve the equivalent result using a function (possibly even an inline function if you are using C99) in place of the code in the macro. You still need a macro to invoke that function because one of the arguments is a 'type name' and you can't pass those to functions.
See the answer by @pmg for an illustration of the type of function and macro using it.
精彩评论