Tutorial :Why would someone define a C macro with unused arguments / parameters?



Question:

I was browsing some code and I came across this macro definition

#define D(x) do { } while (0)  

And its used in the code like this,

D(("couldn't identify user %s", user));  

I ran the code, and that particular line doesn't do anything. So, why would some one define a macro like that?

In case you're wondering, that macro is defined in the _pam_macros.h header file.


Solution:1

Most likely D is for debugging, and there's an #ifdef elsewhere that makes it do something more useful if debugging is enabled, like output the message or log it to a file. The do/while loop is to make it require a semi-colon at the end, so the user can call it as D(...); instead of just D(...) (see this post)


Solution:2

It's done so that if you forget to add a ; at the end of the macro, it causes an error on compile, as it would if it were a function.

If you made this (admitted useless) macro:

#define DBG(x,y) printf ("Debug output %d\n", x); printf ("  %d\n", x+y);   

you can call the macro like this:

void someFun ()  {    DBG(10,0)    DBG(11,40)  }  

And it will compile perfectly fine.

The do {...} while (0) forces you to include the ; at the end, in case the macro is later turned into a function - which often happens. When this change is made, all of sudden you may have thousands of syntax errors to fix. The way I would define it would be:

#define DBG(x,y)                   \  do                                 \  {                                  \    printf ("Debug output %d\n", x); \    printf ("  %d\n", x+y);          \  } while (0)  

Now you must include a ; at the end of the macro. Remember, macros literally replace code during the preprocessor phase.

Now - also consider what would happen if you did this with both macros:

if (x==y)    DBG(x,y);  

It would always print the sum of x and y, regardless of what the if evaluated to if you used the first macro shown.

You're probably thinking, that this would fix it:

#define DBG(x,y) {printf ("Debug output %d\n", x); printf ("  %d\n", x+y);}   

And it would, but you're right back to being able to forget the ';' again.

Clean code isn't necessarily good code, but great code written like garbage will make you think the code sucks. Develop good habits because 5 months down the road, you might have to pull out some code you thought you were done with, and you're going to hate your past self for screwing you over.

Now in your case, the macro wasn't turned into a function, it was simply removed or never populated.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »