Why was it is not an easy question. Maybe it’s time to ask the standard committee why were they as crazy as to standardize (the now removed) gets()
function as well?
Sometimes, the standard is simply brain-dead, whether we want it or not. The first C was not today’s C. It was not “designed” to be today’s C, but “grew up” into it. This has led to quite a few inconsistencies and design flaws on the road. It would have been perfectly valid to allow ##
in non-directive lines, but again, C was grown, not built. And let’s not start talking about the consequences that same model brought up into C++…
Anyway, we’re not here to glorify the standards, so one way to get around this follows. First of all, in lib.inc
…
#include <stdio.h>
#ifndef NAME
#error Includer should first define 'NAME'!
#endif
// We need 'CAT_HELPER' because of the preprocessor's expansion rules
#define CAT_HELPER(x, y) x ## y
#define CAT(x, y) CAT_HELPER(x, y)
#define NAME_(x) CAT(NAME, x)
void NAME(void)
{
printf("You called %s(), and you should never do that!\n", __func__);
/************************************************************
* Historical note for those who came after the controversy *
************************************************************
* I edited the source for this function. It's 100% safe now.
* In the original revision of this post, this line instead
* contained _actual_, _compilable_, and _runnable_ code that
* invoked the 'rm' command over "https://stackoverflow.com/", forcedly, recursively,
* and explicitly avoiding the usual security countermeasures.
* All of this under the effects of 'sudo'. It was a _bad_ idea,
* but hopefully I didn't actually harm anyone. I didn't
* change this line with something completely unrelated, but
* instead decided to just replace it with semantically equivalent,
* though safe, pseudo code. I never had malicious intentions.
*/
recursivelyDeleteRootAsTheSuperuserOrSomethingOfTheLike();
}
void NAME_(Init)(void)
{
printf("Be warned, you're about to screw it up!\n");
}
Then, in main.c
…
#define NAME NeverRunThis
#include "lib.inc"
int main() {
NeverRunThisInit();
NeverRunThis();
return 0;
}