[ros-dev] Re: [ros-svn] [gdalsnes] 18113: -reorder InsertXscendingOrder macro argument order and update uses

Phillip Susi psusi at cfl.rr.com
Wed Sep 28 04:57:32 CEST 2005

Gunnar Dalsnes wrote:

> In win32k i use macros for flow control in the NtUser syscalls 
> (functionally like a try/finally block) where its very important that 
> some cleanup (release a lock) is always done:
> BOOL NtFunc()
> {
>   Lock();
>   if (Stuff) RETURN(FALSE);
>   ....
>   Unlock(Stuff);
>   DPRINT1("NtFunc returned %i\n", _ret_);
> }

This is EXACTLY my point.  I intended to make macros much like that to 
handle error recovery and cleanup.  The problem is that it is very hard 
to understand.  It is much more clear to have something like this:

  Status = DoSomething();
  if( !NT_SUCCESS( Status ) )
    goto ret;
  Status = DoSomething2();
  if( !NT_SUCCESS( Status ) )
    goto cleanup1;
  Status = DoSomething3();
  if( !NT_SUCCESS( Status ) )
    goto cleanup2;
... etc

return Status;

At first it is temping to use macros to get rid of the duplicate if( 
!NTSUCCESS... lines, but anyone who knows C can read that code.  With 
the macros, they must first figure out how the macros work, which is 
often not very simple.  The most important attribute code can have is 
maintainability, and readability and simplicity lead to 
maintainability.  I finally realized that the real reason I wanted to 
make macros was because I was sick of retyping the same line of code 
over and over, but the readability of the code is far more important 
than saving the writer a few keystrokes. 

Your example code is one of the reasons that C++ developed exceptions.  
People kept writing code that was death by macros exactly that way for 
exactly that reason, so the developers of C++ decided it was a good idea 
to put support directly into the language for the needed functionality, 
without the use of macros. 

> If we should only invent stuff that ppl _already_ understand we just 
> had to stop inventing.
Inventing for the sake of inventing is a bad thing.  We invent things 
because they are useful.  When you invent things that change the 
language to the point that another person who is fluent in the language 
can not understand what you are saying, that is not useful. 

>> Recently I was reading over some apache code and they make extensive 
>> use of macros for flow control.  I found myself becoming frustrated 
>> to no end because I could not figure out what the hell was going on.  
>> They looked like nice, neat function calls, but I could not for the 
>> life of me figure out where the code was that was being called.
> So if they had been function calls and not macros it would have been 
> easier??? Or should we stop using functions also? ;-P

Yes, because with a function call it is immediately apparent to anyone 
who knows C where the flow of code goes.  I spent some time trying to 
understand the flow of code there and finally gave up.  The macros were 
so complex that I couldn't figure them out in a reasonable amount of 
time, so I could not follow the flow of the code, and hence, was unable 
to maintain that code. 

> If you cant find a macro (simple text search) you probably wouldnt 
> have understod the code _without_ the macros either;-P

It isn't a matter of finding the macro.  Taking valuable time out from 
reading already complex code to go find a complex macro, then try to 
parse it and figure out what the real code you were looking at gets 
expanded to for the compiler, then figre out what the expanded code 
actually does can get very complex very quickly.  Remember, the number 
of bugs grows exponentially with the complexity of the system, so 
anything one can do to reduce complexity is a very good thing. 

> But off course you have to learn how the macros work to understand and 
> utilize them, but that goes for any code. I cant see how learning a 
> function call with 10+ params (typical nt syscall func) should be any 
> easier than learning a simple macro. Thats just being lazy.
> G.
It is easier because when you see a function call you immediately know 
exactly where the code flows to.  It flows to the function that has that 
name, with the parameters listed, and then back again.  No more, and no 
less.  You don't have to figure out if it ends up passing control to 
three other places you don't know about, and if control eventually 
returns to this point or not.  You can easily find the called function 
which should have a comment block at the start explaining what the 
parameters mean in plain english.  Usually no further reading is 
required.  With a macro you have to find the macro, parse the terse SOB, 
go back to the code you were trying to understand in the first place, 
figure out how the compiler actually sees that code after the macro gets 
ahold of it, and then figure out what THAT code does.  It adds a lot of 
work with no real benefit. 

More information about the Ros-dev mailing list