Переделать макрос в функцию
От: Аноним  
Дата: 03.09.09 10:44
Оценка:
Сабж. Как можно сделать подобное в этом коде? Если бы не поле operand, то делается всё просто.

struct foo {
    int foo_a;
    int foo_b;
    int foo_c;
};

struct barstruct {
    int c;
    int d;

    foo * get_foo(int n) { return &f; }
private:
    foo f;
};

#define FUNC(res, operand) \
else if (fillbuff(buf) == res) \
{ \
    foo * f = bar.get_foo( bar.c );    \
    if (f) \
        return f->operand; \
}

int fillbuff(char const * buf)
{
    int i;
    /// ...
    return i;
}

int main()
{
    //...
    barstruct bar;
    char * buf;
    if (fillbuff(buf) == 0) {
        return 0;
    }
    FUNC(1, foo_a)
    FUNC(2, foo_b)
    FUNC(3, foo_c)
    //...
}
Re: Переделать макрос в функцию
От: Alexander G Украина  
Дата: 03.09.09 10:57
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сабж. Как можно сделать подобное в этом коде? Если бы не поле operand, то делается всё просто.



int func(int res, foo::*int operand)
{
...
return f->*operand;
}
...
int func(1, &foo::foo_a);
Русский военный корабль идёт ко дну!
Re: Переделать макрос в функцию
От: rg45 СССР  
Дата: 03.09.09 12:34
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Сабж. Как можно сделать подобное в этом коде? Если бы не поле operand, то делается всё просто.

А>...

Давненько я такого кошмара не видел, это во истину шедевр А переделать макрос FUNC в функцию без изменения окружающего кода невозможно по той простой причине, этот макрос ветвит вызывающий код на целых три(!) ветки.
--
Re[2]: Переделать макрос в функцию
От: rg45 СССР  
Дата: 03.09.09 13:10
Оценка:
Здравствуйте, rg45, Вы писали:

R>Здравствуйте, Аноним, Вы писали:


А>>Сабж. Как можно сделать подобное в этом коде? Если бы не поле operand, то делается всё просто.

А>>...

R>Давненько я такого кошмара не видел, это во истину шедевр А переделать макрос FUNC в функцию без изменения окружающего кода невозможно по той простой причине, этот макрос ветвит вызывающий код на целых три(!) ветки.


Чтобы не выглядеть неконструктивным критиканом, предложу вариант рефакторинга. Хотя, сразу должен сказать, что у меня возникли сомнения в том, что автор этого кода понимал ЧТО он делает. Особенно странным выглядит множественный вызов функции fillbuff в то время, когда выполняется анализ результата этой же функции.

Тем, не менее, не смотря на кажущуюся (мне, по крайней мере) бессмысленность этого кода, предложенный ниже вариант по своему эффекту полностью идентичен исходному.
int main()
{
  struct
  {
    int result_code;
    int foo::*field; 
  } cases[] = {
    {1, &foo::foo_a},
    {2, &foo::foo_b},
    {3, &foo::foo_c},
  };

  const int cases_count = sizeof(cases) / sizeof(*cases);

  barstruct bar;
  char * buf;

  if (fillbuff(buf) == 0) 
    return 0;

  for (int i = 0; i < cases_count; ++i)
    if (fillbuff(buf) == cases[i].result_code)
    {
      foo * f = bar.get_foo( bar.c );
      if(!f)
        break;
      return f->*cases[i].field;
    }
}
--
Re[3]: Переделать макрос в функцию
От: hmmr_  
Дата: 03.09.09 14:01
Оценка:
R>Тем, не менее, не смотря на кажущуюся (мне, по крайней мере) бессмысленность этого кода, предложенный ниже вариант по своему эффекту полностью идентичен исходному.
R>
R>int main()
R>{
R>  struct
R>  {
R>    int result_code;
R>    int foo::*field; 
R>  } cases[] = {
R>    {1, &foo::foo_a},
R>    {2, &foo::foo_b},
R>    {3, &foo::foo_c},
R>  };

R>  const int cases_count = sizeof(cases) / sizeof(*cases);

R>  barstruct bar;
R>  char * buf;

R>  if (fillbuff(buf) == 0) 
R>    return 0;

R>  for (int i = 0; i < cases_count; ++i)
R>    if (fillbuff(buf) == cases[i].result_code)
R>    {
R>      foo * f = bar.get_foo( bar.c );
R>      if(!f)
R>        break;
R>      return f->*cases[i].field;
R>    }
R>}
R>


Привиденный пример синтетический, просто для того чтобы показать от чего хочется избавится. Здесь интересует прежде всего не оптимизация, а какими путями можно избавится от макроса. Учитывая что во время работы fillbuff динамически создаются различные структуры в barstruct и их количество не известно при компиляции.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.