2010-02-24 16 views
5

Czy możliwe jest dodanie domyślnych argumentów przed zmienną argument w makro wariasu? np mam wersję makro coś podobnegoDodawanie domyślnych argumentów do makra warstwowego

#define MACRO(arg1, ...) func(arg1, ##__VA_ARGS__) 

Chciałbym dodać jeszcze 2 domyślnych argumentów makra przed zmiennymi argumentami tak, że nie powinno mieć wpływu na poprzednią wersję. Na przykład:

#define MACRO(arg1, arg2 = "", arg3 = "", ...) func(arg1, arg2, arg3, ##__VA_ARGS__) 

Każda pomoc będzie doceniona.

+1

C nie obsługuje domyślne argumenty. Czy masz na myśli C++? –

+0

Nie jestem pewien Czy zrozumiesz, czy

#define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__)
nie działa? – philant

+0

Tak. Zapomniałem wspomnieć. To jest dla C++. Dzięki – vishal

Odpowiedz

4

Nie sądzę, że to możliwe. W jaki sposób kompilator/preprocesor wie, czy drugi i trzeci argument są częścią zmiennych argumentów lub zastępują wartości domyślne? To jest powód, dla którego parametry z wartościami domyślnymi muszą znajdować się na ostatniej pozycji w funkcji.

Obawiam się, że będziesz musiał mieć dwa makra lub trzy, jeśli będziesz w stanie podać arg2 i użyć domyślnej wartości arg3, ale jest to podatne na błędy.

#define MACRO(arg1, ...) func(arg1, "", "", ##__VA_ARGS__) 
#define MACRO2(arg1, arg2, ...) func(arg1, arg2, "", ##__VA_ARGS__) 
#define MACRO3(arg1, arg2, arg3, ...) func(arg1, arg2, arg3, ##__VA_ARGS__) 
5

Co można zrobić:

struct foo { 
    int aaa; 
    char bbb; 
    char *ccc; 
}; 

#define BAR(...) bar((struct foo){__VA_ARGS__}) 

void bar(struct foo baz) 
    /* set defaults */ 
    if (!baz.aaa) 
     baz.aaa = 10; 
    if (!baz.bbb) 
     baz.bbb = 'z'; 
    if (!baz.ccc) 
     baz.ccc = "default"; 

    printf("%d, %c, %s\n", baz.aaa, baz.bbb, baz.ccc); 
} 

... 
BAR();      // prints "10, z, default" 
BAR(5);     // prints "5, z, default" 
BAR(5,'b');    // prints "5, b, default" 
BAR(5, 'b', "something"); // prints "5, b, something" 

źle o tym - zerowej parametr jest traktowany jak żaden parametr, np BAR(0, 'c') będzie produkować String 10, c, default

+0

Niestety, nie rozwiąże to problemu, jeśli domyślne argumenty mają być nazwami typów. – PSkocik

+0

@PSkocik Co masz na myśli? Czy mógłbyś rozwinąć? – qrdl

0

nie jako odpowiedzi na swoje pytanie, ale jako sposób po prostu rozwiązać problem:

#define MACRO(arg1, ...)   \ 
    /* pre-treatment */   \ 
    func(arg1, ##__VA_ARGS__)  \ 
    /* post-treatment */   \ 

void func (type1 arg1, type2 arg2 = "", type3 arg3 = "", ...);