now, if you want to be perfectionist, there are criminal ways and correct ways to use macros.
this is the ultimate guide to portability and macro usage: http://doc.cat-v.org/henry_spencer/ifdef_considered_harmful.pdf
briefly, try to follow these three rules:
- Never, ever, write conditional macros inside "ordinary" code.
- Conversely, always keep it at "the top", confined inside a function or something equivalent.
- Always test for features, never test for platforms.
I hope the following C code makes sense to demonstrate the above rules
this is okay:
#ifdef DISCORD
#define online_presence(STATUS) TellEveryoneAtDiscordYouArePlaying("My Epic Game", status[STATUS]);
#else
#define online_presence(STATUS) ((void)0) // Do nothing! Yes, nothing!
#endif
#ifdef NEWGROUNDS
#define ng_unlock(MEDAL) TellNewgroundsYouEarned(MEDAL)
#else
#define ng_unlock(MEDAL) ((void)0) // Do nothing!
#endif
void unlock(enum medal medal) {
if (!is_unlocked[medal]) {
StartAnimationForMedal(medal);
is_unlocked[medal] = true;
ng_unlock(medal);
}
}
void damage_player(Player *player, int amount)
{
if ((player->health -= amount) > 0)
PlayHurtAnimation(player);
else {
unlock(MEDAL_FIRST_DEATH);
PlayDeathAnimation(player);
EndMatch();
online_presence(STATUS_SELECTING_LEVEL);
}
}
the following is a war crime:
void damage_player(Player *player, int amount)
{
if ((player->health -= amount) > 0)
PlayHurtAnimation(player);
else {
#ifdef HTML5
if (!is_unlocked[MEDAL_FIRST_DEATH]) {
StartAnimationForMedal(MEDAL_FIRST_DEATH);
is_unlocked[MEDAL_FIRST_DETH] = true;
TellNewgroundsYouEarned(MEDAL_FIRST_DEATH);
}
#endif
PlayDeathAnimation(player);
EndMatch();
#ifdef WINDOWS
TellEveryoneAtDiscordYouArePlaying("My Epic Game", status[STATUS_SELECTING_LEVEL]);
#endif
}
}
happy coding!