简体   繁体   中英

Is it a good idea to apply some basic macros to simplify code in a large project?

I've been working on a foundational c++ library for some time now, and there are a variety of ideas I've had that could really simplify the code writing and managing process. One of these is the concept of introducing some macros to help simplify statements that appear very often, but are a bit more complicated than should be necessary.

For example, I've come up with this basic macro to simplify the most common type of for loop:

#define loop(v,n) for(unsigned long v=0; v<n; ++v)

This would enable you to replace those clunky for loops you see so much of:

for (int i = 0; i < max_things; i++)

With something much easier to write, and even slightly more efficient:

loop (i, max_things)

Is it a good idea to use conventions like this? Are there any problems you might run into with different types of compilers? Would it just be too confusing for someone unfamiliar with the macro(s)?

IMHO this is generally a bad idea. You are essentially changing well known and understood syntax to something of your own invention. Before long you may find that you have re-invented the language . :)

I would say it depends upon whether you expect anyone else to ever have to make sense of your code. If it's only ever going to be you in there, then I don't see a problem with the macros.

If anyone else is ever going to have to look at this code, then the macros are going to cause problems. The other person won't know what they are or what they do (no matter how readable and obvious they seem to you) and will have to go hunting for them when they first run across them. The result will be to make your code unreadable to anyone but yourself - anyone using it will essentially have to learn a new language and program at the same time.

And since the chances of it just being you dealing with the code are pretty much nil if you hope the code to be a library that will be for more than just your personal use - then I'd go with don't .

No, not a good idea.


  int max = 23;
  loop(i, ++max)...

It is, however, a good idea to refactor commonly used code into reusable components and then reuse instead of copy. You should do this through writing functions similar to the standard algorithms like std::find(). For instance:


template < typename Function >
void loop(size_t count, Function f)
{
  for (size_t i = 0; i < count, ++i) f();
}

This is a much safer approach:


int max = 23;
loop(++max, boost::bind(....));

I think you've provided one strong argument against this macro with your example usage. You changed the loop iterator type from int to unsigned long . That has nothing to do with how much typing you want to do, so why change it?

That cumbersome for loop specifies the start value, end value, type and name of the iterator. Even if we assume the final part will always be ++name , and we're happy to stick to that, you have two choices - remove some of the flexibility or type it all out every time. You've opted to remove flexibility, but you also seem to be using that flexibility in your code base.

In Unix, I find that by the time I want to create an alias for a command I use all the time, the command is on my fingers, and I'd have a harder time remembering the syntax of my alias than the original command.

The same applies here -- by the time you use an idiom so much that you want to create a macro for it, the idiom will be on you fingers and cause you more pain than just typing out the code.

Getting rid of the for loops is generally a good idea -- but replacing them with macros is not. I'd take a long, hard look at the standard library algorithms instead.

It's a question of where you're getting your value. Is typing those 15 extra characters in your loops really what's slowing your development down? Probably not. If you've got multiple lines of confusing, unavoidable boilerplate popping up all over the place, then you can and should look for ways to avoid repeating yourself, such as creating useful functions, cleaning up your class hierarchies, or using templates.

But the same optimization rules apply to writing code as to running it: optimizing small things with little effect is not really a good use of time or energy.

Steve Jessop makes a good point. Macros have their uses. If I may expound upon his statements, I would go so far as to say that the argument for or against macros comes down to "It depends". If you make your macros without careful thought, you risk making future maintaners' lives harder. On the other hand, using the wxWidgets library requires using library provided macros to connect your code with the gui library. In this case, the macros lower the barrier of entry for using the library, as magic whose innards are irrelevant to understanding how to work with the library are hidden away from the user. In this case, the user is saved from having to understand things they really don't need to know about, and can be argued that this is a "Good" use of macros. Also, wxWidgets clearly documents how these macros are supposed to be used. So make sure that what you hide isn't something that is going to need to be understood by someone else coming in.

Or, if its just for your use, knock yourself out.

Apart from the maintenance/comprehension problems mentionned by others, you'll also have a hard time breaking and single-stepping through macro code.

One area where I think macros might be acceptable would be for populating large data structures with constants/litterals (when it can save an excessive amount of typing). You normally would not single-step through such code.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM