English 中文(简体)
Removing macro in legacy code
原标题:

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.

问题回答

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

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).

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.

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

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.





相关问题
Undefined reference

I m getting this linker error. I know a way around it, but it s bugging me because another part of the project s linking fine and it s designed almost identically. First, I have namespace LCD. Then I ...

C++ Equivalent of Tidy

Is there an equivalent to tidy for HTML code for C++? I have searched on the internet, but I find nothing but C++ wrappers for tidy, etc... I think the keyword tidy is what has me hung up. I am ...

Template Classes in C++ ... a required skill set?

I m new to C++ and am wondering how much time I should invest in learning how to implement template classes. Are they widely used in industry, or is this something I should move through quickly?

Print possible strings created from a Number

Given a 10 digit Telephone Number, we have to print all possible strings created from that. The mapping of the numbers is the one as exactly on a phone s keypad. i.e. for 1,0-> No Letter for 2->...

typedef ing STL wstring

Why is it when i do the following i get errors when relating to with wchar_t? namespace Foo { typedef std::wstring String; } Now i declare all my strings as Foo::String through out the program, ...

C# Marshal / Pinvoke CBitmap?

I cannot figure out how to marshal a C++ CBitmap to a C# Bitmap or Image class. My import looks like this: [DllImport(@"test.dll", CharSet = CharSet.Unicode)] public static extern IntPtr ...

Window iconification status via Xlib

Is it possible to check with the means of pure X11/Xlib only whether the given window is iconified/minimized, and, if it is, how?

热门标签