> Why use a do loop ?
It's one of the standard techniques to ensure that a multi-line macro such as this always appears as a single statement.
See http://www.c-faq.com/cpp/multistmt.html
@OP
>#define allocate_cube(type, var, x, y, z) \
> do { \
> (var) = malloc(sizeof(type **) * (x)); \
You don't need to specify the type as a parameter to the macro. All the size information is available via the var, eg.
#define allocate_cube(var, x, y, z) \
do { \
(var) = malloc(sizeof(*var) * (x)); \
The general form being p = malloc ( n * sizeof *p );
This fixes the problem of doing something dumb, but hard to trace if it happens to work first time around, like this. int ***array;
array = allocate_cube(double, array, 5, 10, 15);
> Another issue (as I see it) with macro vs functions in this case is that my macro is type-neutral
Or type-unsafe, depending on your point of view.
In reality, how many types are you going to be dealing with, and how often do you need a new type?
AD's suggestion of a function could be implemented simply as
int ***allocate_int_cube ( int x, int y, int z ) {
int ***result = alloc_cube( result, x, y, z );
return result;
}
The macro still does all the donkey work, but it's use is tightly controlled to just a small part of the overall program. The bonus to you is something you can debug with, and a measure of type safety.