2

I came across a c++ code where a function was defined in the header section of the file as follows

#define APPEND_VALUE(X, Y, I)\ {\ int idx = (Y*100+X);\ int idxn = idx + ValueCount[idx];\ TempVector[idxn] = I;\ CountVector[idx] += 1;\ } 

(Note that this is not all the code and TempVector and CountVector was defined elsewhere)

Later in the code APPEND_VALUE was used like any other function. I was wondering what is the difference between the above (#define APPEND_VALUE) code and the below code

void APPEND_VALUE(int X, int Y, int I) { int idx = (Y*100+X); int idxn = idx + ValueCount[idx]; TempVector[idxn] = I; CountVector[idx] += 1; } 

What is the advantage of using one over the other? also is there a technical name for defining a function as show in the first code(the one using #define).

8
  • 6
    the first version does not work for APPEND_VALUE(5, 2+3, 5);. Commented Jul 9, 2018 at 10:50
  • 4
    The #define version is still a macro. The code is expanded at the invocation site. It has all the expected problems (with macros) including namespace pollution and unexpected parameter behaviour. Commented Jul 9, 2018 at 10:52
  • 2
    @mch: But judicious use of parentheses could address that. Commented Jul 9, 2018 at 10:52
  • Preprocessor macros (which is what you have, not functions) are expanded before the parser of the compiler sees the code. So when the preprocessor sees APPEND_VALUE(...) (with proper arguments of course) then it basically replaces that with the body of the macro. Most compilers have options to let you see the code after preprocessing, I suggest you do that to see how the macro have been expanded. Commented Jul 9, 2018 at 10:53
  • 3
    Possible duplicate of Macro vs Function in C Commented Jul 9, 2018 at 11:00

1 Answer 1

2

#define is part of something called the "preprocessor." Essentially, this is the code that is processed before the C document is compiled. Most of the preprocessor code is in a file with a ".h" extension (which is why you may have seen that when importing libraries).

The preprocessor language is primitive. For example, if it performs a "textual substitution [with] missing parentheses", the result of the preprocessor function may not be what you intended it to return (credit: @Deduplicator). Take a look at this post for an example: #define Square(x) (x*(x)). For this reason, and many others, I would prefer coding it in the regular C language when possible (just note there are many cases where the preprocessor may be faster and more helpful). Hope this helps!

Sign up to request clarification or add additional context in comments.

10 Comments

"...there are many cases where the preprocessor may be more faster and helpful" Any example?
Lexical binding of expressions is the least of your concerns. Side effects are the real problem.
@jszpilewski, in response to your question: A good example of where the preprocessor can be helpful is when you prove your code with contracts. For example, you may insert thousands of assert statements during production. But after the code is complete, you want to get rid of all the assert statement (to save processing power). You can redefine ASSERT in the preprocessor to do nothing (rather than individually get rid of all the assert statement). This will also allow you to use the assert statements later, if need be
Since when does the preprocessor disdain operator-precedence?
@kamykam That's not about operator-precedence, but textual substitution, a completely different thing.
|

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.