2009-10-26 3 views
4

Как я могу выполнить следующие действия в соответствии с ISO (C99)?ISO C эквивалент брекет-групп в выражениях

#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: для компиляции я использую: НКА -s = c99 -pedantic ...

ответ

4

Вы не должны ставить тест на malloc() в assert(): он не будет составлен, когда вы выполните сборку выпуска. Я не использовал assert() в следующей программе.

#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; 
} 
+1

Я буду использовать функцию, как вы предлагали, и избегать использования heisenbug (спасибо, что указали ее). – Alexandru

+0

+1 для heisenbug :) – pmg

4

Нет стандартного эквивалента расширения GCC, которое вы используете.

Вы можете получить эквивалентный результат, используя функцию (возможно, даже встроенную функцию, если вы используете C99) вместо кода в макросе. Вам все еще нужен макрос для вызова этой функции, потому что один из аргументов - это «имя типа», и вы не можете передать их функциям.

См. Ответ на @pmg для иллюстрации типа функции и макроса, использующего его.