Удаление макроса в устаревшем коде - PullRequest
0 голосов
/ 12 ноября 2009

У меня много устаревшего кода, использующего макрос вида:

#define FXX(x) pField->GetValue(x)

Переменная силы макроса pField находится в области видимости:

.....
FIELD *pField = ....
.....
int i = FXX(3);
int j = FXX(5);

Есть ли способ заменить макрос, не касаясь кода пользователя?

Поскольку у FXX (x) есть стиль вызова функции, я подумал о встроенной функции или о чем-то подобном.

UPD: Люди просто привыкли к макросу, и я хочу оставить его как есть.

Ответы [ 5 ]

3 голосов
/ 12 ноября 2009

Что такое pField (помимо прекрасного примера мерзости, которая называется Systems Hungarian)? Если, случайно, это глобальная переменная или синглтон или что-то, что нам нужно только одно, мы могли бы сделать хитрый трюк, подобный этому:

int FFX(int x)
{
    static FIELD *pField = ...; // remove this line if pField is global
    return pField->GetValue(x);
}

Измените типы int на любые типы, с которыми вам нужно работать, или даже шаблон, если вам нужно, чтобы он поддерживал несколько типов.

Другая альтернатива, предложенная @ epatel , состоит в том, чтобы использовать функцию поиска и замены вашего любимого текстового редактора и просто изменить все строки FFX(x) на pField->GetValue(x), что исключает вызов макроса в вашем код. Если вы хотите сохранить вызов функции, вы должны изменить FFX(x) на FFX(pField, x) и изменить макрос на два аргумента (или изменить его на функцию, которая принимает два аргумента). Но в этот момент вы можете просто взять макрос.

Третий вариант - не исправить то, что не сломано. Макрос не особенно хорош, но вы можете столкнуться с большими проблемами, пытаясь удалить его. Макросы не являются порождением сатаны (хотя у этого есть по крайней мере несколько родственников в аду).

3 голосов
/ 12 ноября 2009

Как насчет использования функции поиска и замены в вашем любимом редакторе ... Я думаю, что это будет хорошо работать в примере, который вы привели в своем вопросе. Замените FXX на pField->GetValue, а затем удалите строку #define

1 голос
/ 12 ноября 2009

Вам нужна функция, которая зависит от определяемой переменной. Единственный способ сделать это - объявить эту переменную в той же области видимости, что и функция. Но тогда ваша функция будет использовать эту функцию вместо той, которая объявлена ​​из той, где вызывается ваша функция.

Так что я вполне уверен, что это невозможно.

0 голосов
/ 12 ноября 2009

Я бы оставил все как есть, но только для обсуждения, и в зависимости от того, какие части кода являются «неприкасаемыми», вы можете определить функтор, который принимает pField и инициализируется после того, как переменная создается в том же самом Объем:

class FFX_t {
   FFX_t( FIELD * pField ) : field_(pField) {}
   int operator()( int index ) {
      return field_->GetValue( index );
   }
private:
   FIELD *field_;
};
// usage:
void f() {
   FIELD * pField = //...
   FFX_t FFX(pField); // added after pField construction
   // ...
   int a = FFX(5);
}

Но я настаиваю на том, что изменение рабочего кода ради него, когда он действительно не добавит никакого значения, бесполезно.

0 голосов
/ 12 ноября 2009

Хорошо, если вы можете поместить это определение функции, где pField уже находится в области видимости:

int FXX(int x) { return pField->GetValue(x); }

В противном случае, невозможно включить pField в функцию, не затрагивая существующий код.

Это может быть случай, когда использование макроса является лучшей альтернативой. Макросы могут быть злыми, но иногда они необходимы. Смотри http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15

...