luca
luca

Reputation: 7546

Inline code in C++: options and their advantages/disadvantages

What are the methods to achieve inline code in C++? I can only think about macros and inline functions. Are there more alternatives in C++11/17/20 (e.g. lambda) ? Advantages and disadvantages?

// do macros still make sense in modern C++ standards?
#define square(x) ((x)*(x))

// is this a good alternative to macros?
template <class T> inline T square(T x) { return x * x; }

EDIT: changed comment from "are macros still encouraged...?" to "do macros still make sense...?"

Upvotes: 1

Views: 157

Answers (5)

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20171

Macros have a big dis-advantage: They are namespace agnostic.

Imagine what happens if I extend your sample:

// are macros still encouraged in modern C++ standards?
#define square(x) ((x)*(x))

namespace My {

int square(int x) { return x * x; }

} // namespace My

So, IMHO, the answer is NO.

Remember that in C (where the preprocessor was introduced), there were no namespaces, and still have not been added until now.


Demo:

#define square(x) ((x)*(x))

namespace My {

int square(int x) { return x * x; }

} // namespace My

Preprocessed:

namespace My {

int ((int x)*(int x)) { return x * x; }

}

int main()
{
  std::cout << My::((10)*(10));
}

Demo on coliru

in opposition to:

#include <iostream>

template <typename T>
T square(T x) { return x * x; }

namespace My {

int square(int x) { return x * x; }

} // namespace My

int main()
{
  std::cout << My::square(10);
}

Output:

100

Demo on coliru

Upvotes: 3

StPiere
StPiere

Reputation: 4263

// is this a good alternative to macros?
template <class T> inline T square(T x) { return x * x; }

Yes, this is the preferred way. (Although templates in general don't require inline, whereas explicit template specializations and instantiations do, it is ok to be consistent and write what one means).

Also note that constexpr functions and constructors are implicitly inline.

Also note that using final (where appropriate) in the context of virtual overloading can help inline even some virtual methods (check this post for some examples and explanation).

Upvotes: 5

Jack Lilhammers
Jack Lilhammers

Reputation: 1247

Macros should be the last resort in C++.
They're not inherently bad, but they're not checked by the compiler.

Macro expansion is a little more than text replacement done before compiling, therefore you're writing code that will be checked only after the expansion.
That means that if you make a mistake find the error could be harder, also debugging will be harder, because you won't be able to jump into the macro code. Also, you have to be careful with parentheses and with multiple evaluation.

Last but not least, all the other things pointed out by the other answers apply too.

Upvotes: 1

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 123450

Macros never were encouraged. Consider that the macro is not doing the same as the function eg here:

int foo() {
   static int x = 0;
   ++x;
   return x;
}

std::cout << square(foo());

And that is just one downside of the macro. If you want a function that takes a parameter and returns a value then that is not a macro.

Upvotes: 3

Alex Guteniev
Alex Guteniev

Reputation: 13759

It smells like "opinion-based", some people tend to dislike macros more than others.

Usual disadvantages of macros:

  • they evaluate argument as many times as it is encountered (twice in your case)
  • more error prone (don't forget parentheses)
  • ignore program structure (don't belong to a namespace, and now you cannot have anything else named square, even as a class method

To mitigate the later one, name macros with ALL_CAPS, and don't name anything else like this.

The advantages of macros are:

  • C compatibility
  • Ability to have arbitrary pieces of code in macros, not just (inline) functions

Upvotes: 1

Related Questions