Saving Magic for Macros

RMAG news

We often find ourselves in the middle of writing a function that we cannot bring ourselves to simplify further. The ones which end up relying on some kind of inexplicable “magic” that cannot be abstracted away.

Instead of writing these as functions, consider using macros instead.

Macros are defined using the #define directive and are effectively a copy-paste replacement where they are used with appropriate parameter substitutions.

#include <stdio.h>

#define PRINT_MESSAGE(message) printf(“%sn”, (message))

int main(void) {
PRINT_MESSAGE(“Hello, world!”);
return 0;
}

Macros are incredibly powerful since they accept any token as a parameter. So, you could potentially also do this.

#define PERFORM_OPERATION(number_1, number_2, operator)
((number_1) operator (number_2))

int main(void) {
int a = PERFORM_OPERATION(1, 2, +); // 3
int b = PERFORM_OPERATION(1, 2, ); // -1
int c = PERFORM_OPERATION(5, 2, *); // 10
int c = PERFORM_OPERATION(4, 2, /); // 2

return 0;
}

But, my personal favourite use of macros is to create generic versions of certain often used procedures. Here’s one that is used to swap two values of any given data type.

#include <stdbool.h>
#include
<stdlib.h>

#define SWAP(value_1, value_2, type)
do
{
type* temp = malloc(sizeof(type));
*temp = value_1;
value_1 = value_2;
value_2 = *temp;
free(temp);
}
while (false)

Let me try to explain the weirdness. Since we’re creating a variable and since macros are effectively a copy-paste substitution, we have to limit the variable’s scope. So, we can place it in a separate block like this do-while block that only executes once.

This function would have been a pain to write normally since there is no direct way to pass the data-type to a function in C. In situations like this, it is often much easier to write a simple macro than to create multiple long and similar functions.

Leave a Reply

Your email address will not be published. Required fields are marked *