What is the disadvantage of using a preprocessor to define a function call?

I would like to know that the cons use the preprocessor in this way:

#define SOME_FUNCTION someFunction(someArgument) 

Mostly I feel this is wrong (or, of course, not the best practice), but I'm not sure why ... my preprocessor skills are rusty at best.

+6
c ++ c-preprocessor
source share
9 answers

Disadvantage? Typically, a macro definition is not included in an executable symbol table. A little harder to debug.

+5
source share

The problem is that re = arguments are evaluated every time they are used:

 #define MIN(A,B) ((A) < (B))?(A):(B); 

Note that I have to wrap all arguments in '(' ')' to make sure that the expression is evaluated differently. But what happens if we do this?

 int s = MIN(++current,Max); 

Coding this, I expect the current to be increased once before the function is called. But since this is a macro, it increases once in the test and a second time if it is still less than Max

+5
source share

There are a few issues you might think about:

  • In C ++, a macro does not have a namespace or class, so it is the same everywhere. An example of this is the failed min and max, somewhere in windows.h. If you program for Windows and turn on windows.h and want to write std :: numeric_limits :: max (), then max will be replaced with some code ... This leaves incompatible code after the preprocessor starts. (Well, there are ways to disable min / max macros in windows.h, but this is still a bad design!)
  • A macro cannot be debugged. The debugger will stop at the line that the macro does not use in the code inside the macro ...
  • Possible overestimation of macro parameters (this can be prevented if the macro has a block with local variables, but this will make debugging even worse!)
+2
source share

Well, if you have to do this (and there are some cases where you could), then you should at least define the macro as “functional”, thus:

 #define SOME_FUNCTION() someFunction(defaultArgument) 

otherwise, you should write code that looks like assigning a constant when it was a function call; i.e;

 x = SOME_FUNCTION ; // hidden function call 

but with a “functional” macro that you would have to write:

 x = SOME_FUNCTION() ; // shorthand function-call with default argument 

Which better matches the syntax of the preprocessor with the syntax of the language.

Generally, macros like functions are best avoided, but some are more insidious, others are by no means the worst case. However, you can just as easily write the shell of functions in C, or in C ++ use the default argument, and that would be preferable in most cases.

+1
source share

This is sometimes useful in a very closed area to define process steps in a more readable way:

 void myfunc() { DO_STEP_ONE; THEN_ANOTHER_STEP; KEEP_GOING; LAST_STEP; } 

But usually it just makes the code harder to read and understand.

If this does not mean that readers of your code will find out what these #define mean, and this is some short segment, you simply make people look in two places to understand the line of code (at the top of the file and function), and not just one.

I very rarely use this approach.

0
source share

This will depend on the language, compiler, etc. etc....

However, there is nothing wrong with that, as soon as the name implies that these directives are encountered. Compilation process.

The preprocessor removes all constant references by its real value, the entire pseudo-function with the correct code, etc.

0
source share

All problems in computer science can be solved by a different level of indirection

This is one of these additional levels of indirection :-)

Say that at some point the function needs another argument, or you do not need to call it at all, you can change #define once instead of changing all the places where the function is called.

Useful for development, but dangerous to store in working code ... I would run a preprocessor to replace this rule when I have mature code, and I know that I do not need to change it.

0
source share

Why are you looking for the disadvantages of using specific preprocessor code? Using preprocessor macros for anything but conditional compilation (including enabling guards) should automatically be considered bad. The right question is: are there any benefits for a particular use.

The preprocessor macros do not take into account the scope or use. They can ruin perfectly good code in unexpected and hard-to-reach ways. Always avoid them if you have no reason to use it.

0
source share

The downside is that you are hiding the code. The surface is that you are hiding the code.

The disadvantage usually exceeds the growth potential.

Usually this particular approach is practically useless, and if the call no longer looks like

someModule-> someStorage-> functionList [storage.getFunctionName] .pointer-> SomeFunction (... an equally obscure argument ...);

there is no point in doing this. If only the argument is an obscure call, reduce only the argument. If it is only a function, shorten only the function. If both of you, you might be better off

  SOME_FUNCTION(SOME_ARGUMENT); 

If a function is never called with anything else, you can remove it from the list of arguments and get it inside the body of the function. And if a couple repeats very often, in small variations, you can consider wrapper functions.

After you make some mistakes in the macro code, you will learn how to experience pain in order to debug them, and you will not use them lightly.

0
source share

All Articles