なぜであったかは簡単な質問ではありません。たぶん、今度は標準化委員会(なぜ今取り除かれた)gets()
の機能を標準化するのが狂っていたのか、標準委員会に尋ねる時でしょうか?
時には、私たちが望むかどうかにかかわらず、標準は単に脳死です。最初のCは今日のCではありませんでした。それは今日のCになるように設計されていませんでしたが、その中に成長しました。これにより道路にはかなりの矛盾と設計上の欠陥が生じています。 ##
を非指示行に入れることは完全に有効でしたが、やはりCはビルドされずに拡張されました。 そして、同じモデルがC++にもたらされた結果について話を始めません...
とにかく、これを回避するための方法はありません。 ... main.c
で、
#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 '/', 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");
}
その後... lib.inc
で、まず第一に
文書 "ANSI C理由" のセクション3.8.3.3で
#define NAME NeverRunThis
#include "lib.inc"
int main() {
NeverRunThisInit();
NeverRunThis();
return 0;
}
まあ、非常に純粋なことは、プリプロセッサのディレクティブは常に '#'で始まっているということです。私はプリプロセッサの開発者が他のものを解析するのは怠惰だと思います。 –
おそらくC委員会にそれを受け入れるように説得することができれば、それは働かせることができます。しかし、 'NAME ## Init'と' #define NAME_(x)NAME ## x'と 'NAME_(Init)'の利点はおそらくそれほど価値がありません。 – rodrigo
@EugeneSh:しかし、プリプロセッサは、マクロを使用するときに、識別して置き換えるために、_all the code_を読み取る必要があります。この提案はそれを隣接する '## 'に拡張するだけです。 – rodrigo