views:

91

answers:

5

I have a lot of legacy code using macro of the form:

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

The macro forces variable pField be in the scope:

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

Is there way to replace the macro, without touching user code?

Since FXX(x) has a function invocation style, I thought about inline function or something similar.

UPD: People just used to the macro, and I want to remain it as is.

+3  A: 

How about using a find & replace function in your favorite editor...I think it would work fine in the example you gave in your question. Replace FXX with pField->GetValue and then remove the #define line

epatel
A: 

Well, if you can put this function definition where pField is already in scope:

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

Otherwise, there's no way to get pField into the the function without affecting existing code.

This may be a case where using the macro is the best alternative. Macros may be evil, but they are sometimes necessary. See http://www.parashift.com/c++-faq-lite/big-picture.html#faq-6.15

Fred Larson
DProbably don't understand your solution - how pField is seen inside FXX()?
dimba
An example would be if pField were defined as a global. You didn't give a clear indication of its scope.
Fred Larson
+3  A: 

What is pField (besides a fine example of the abomination that is Systems Hungarian)? If, by chance, it's a global variable or a singleton or something that we only need one of, we could do a nifty trick like this:

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

Change the int types to whatever types you need it to operate on, or even a template if you need it to support multiple types.

Another alternative, suggested by @epatel, is to use your favorite text editor's find-and-replace and just change all the FFX(x) lines to pField->GetValue(x), thus eliminating the macro invokation in your code. If you want to keep a function invokation, you culd change FFX(x) to FFX(pField, x) and change the macro to take two arguments (or change it to a function that takes two arguments). But you might as well just take out the macro at that point.

A third alternative, is not to fix that which is not broken. The macro isn't particularly nice, but you may introduce greater problems by trying to remove it. Macros aren't the spawn of Satan (though this one has at least a few relatives in hell).

Chris Lutz
+1  A: 

What you need is a function that relies on a variable being defined. The only way to do that is to declare that variable in the same scope as the function. But then your function would use that one instead of the one declared from where your function is called.

So I'm fairly confident it can't be done.

JohnMcG
A: 

I would leave it as it is, but just for the sake of discussion, and depending on what parts of the code are 'untouchable' you could define a functor that takes a pField and initialize after the variable is created in the same scope:

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);
}

But I insist in that changing working code for the sake of it when it will not really add any value is useless.

David Rodríguez - dribeas