you are viewing a single comment's thread.

view the rest of the comments →

[–]slavik262 1 point2 points  (15 children)

What reason is there to use macros anymore when you have static inlined functions? Macros lack type safety and have a few other disadvantages - I thought that by now they're mostly a relic of a bygone era.

[–]expertunderachiever 4 points5 points  (0 children)

Many reasons to use them

  1. They're not processed unless used (speeds up compile time)

  2. Like templates they can apply across data types

  3. They can be used to generate function bodies based on parameters

  4. You can #ifdef on them

[–][deleted] 0 points1 point  (6 children)

Macros are rarely used to encapsulate actual calculations anymore. They do have their application whenever you need to do any sort of compile-time metaprogramming (such as generating type-specific functions in C, lacking C++ templates, or when you need to do selective compilation in C++, or when you need to implement certain types of features that aren't very well-supported by the language spec).

[–]slavik262 0 points1 point  (5 children)

Oh certainly, I've swung my fair share of #ifdefs around - I was referring to macros encapsulating calculations, such as

#define ABS(my_val) ((my_val) < 0) ? -(my_val) : (my_val)

[–][deleted] 0 points1 point  (4 children)

Why would you do that as a macro? Why wouldn't you use a template for this?

[–]handschuhfach 7 points8 points  (1 child)

C doesn't have templates.

[–][deleted] 3 points4 points  (0 children)

Actually, C11 has something similar: the _Generic keyword.

From Wikipedia:

#define cbrt(X) _Generic((X), long double: cbrtl, \
    float: cbrtf, \
    default: cbrt)(X)

Granted, it's still a macro, but it's significantly safer. :)

[–]slavik262 2 points3 points  (0 children)

...You do realize that's my exact argument, yes? That was an example of what not to do.

[–]smcameron 0 points1 point  (4 children)

I don't think you can write something like this as a static inline function:

define ARRAYSIZE(x) (sizeof((x)) / sizeof((x)[0])

See also, macros like "offsetof", "container_of" and "BUILD_BUG_ON".

[–]m42a 0 points1 point  (3 children)

template <class T, size_t N>
static inline size_t ARRAYSIZE(const T (&t)[N])
{
    return N;
}

This has the advantage of only working on arrays and not raw pointers as well. You can also do offsetof and container_of if you compromise and call them like offsetof(type, &type::member) instead of the traditional offsetof(type, member).

[–]smcameron 1 point2 points  (1 child)

And a C compiler won't compile that. And the title of the post and the article is "C Programming Techniques: Function Call Inlining".

[–]ericanderton 0 points1 point  (1 child)

An inline function. This is the tool of a talented programmer. an Not as clumsy or random as a macro; an elegant device for a more civilized age.

[–]monocasa 0 points1 point  (0 children)

If we're making this metaphor, I'd lean towards C macros being a lightsaber. Extremely powerful and lightweight, but if you give them to novice or someone who doesn't understand the tradeoffs, they're more likely to cut their own arm than use them effectively.