编辑/重新定义常量字符串:是的我知道这个矛盾

时间:2013-02-11 04:44:51

标签: c-preprocessor preprocessor-directive

我正在尝试更改常量变量值,是的我知道我正在做的事情的矛盾但是我有一种疯狂的方法。

你看我用非常类似于 C / C ++的语言编写,称为4dm,但它不允许任何函数以外的代码,所以我试图通过使用预处理器命令来克服这个问题。原因是我可以在语言中实现一种专业化形式。第一步涉及能够编辑常量字符串。

即使这是一种不同的语言,预处理器的运行方式与C和C ++编译器完全相同:

#define MY_STR "abc"
#define CONCAT(s) \
    #define TEMP MY_STR \  // store MY_STR in TEMP_STR
    #undef MY_STR \        // undefine MY_STR
    #define MY_STR TEMP s  // redefine MY_STR so it contains the old value plus the new one

CONCAT(def)
printf("%s\n", MY_STR);  // should hopefully print out "abc def"

以下是连接字符串的简单尝试,但我收到编译错误,说MY_STR is not defined任何想法如何解决这个问题?

#define MY_STR abc
#define TEMP MY_STR
#undef MY_STR
#define MY_STR TEMP def

void test()
{
    print(MY_STR);
}

3 个答案:

答案 0 :(得分:2)

在第一个示例中,您尝试将宏扩展为#define预处理器命令。你做不到;预处理器生成C代码(或其他),宏扩展中看起来像预处理器指令的各种东西实际上不是预处理器指令。这将产生错误,因为宏定义中的#是“stringify”运算符,后面必须跟一个宏参数。 (此外,\必须位于该行的末尾。您无法通过评论关注它。)

在你的第二个例子中,当你写:

#define TEMP MY_STR

这正是它的作用:它将宏TEMP定义为具有值MY_STR(不是MY_STR的宏扩展,只是六个字符的标记MY_STR

之后,你

#define MY_STR TEMP def

将宏MY_STR定义为两个令牌TEMPdef

然后展开MY_STR

print(MY_STR);

导致它被TEMP def替换。扩展再次通过宏处理器,这会导致TEMP替换为MY_STR。那是再次通过宏处理器,但这次MY_STR 扩展,因为您无法在该宏的扩展中扩展宏。所以这次它保持MY_STR,你最终得到:

print(MY_STR def);

MY_STR未定义(宏不是定义),因此编译器抱怨MY_STR未定义。

答案 1 :(得分:0)

一个好的编译器会将一个字符串常量放在一个标记为写保护的块中,任何修改它的尝试都会导致某种操作系统异常。

这不是你在这里所做的 - 你是用旧字符串定义一个新字符串。这适用于C和C ++,并且可能也适用于您的语言。

既然你正在定义自己的语言,你会比我们更清楚它会如何反应!

答案 2 :(得分:0)

关于你试图用CONCAT实现的目标,C99标准的第6.10.3.4节§3(部分引用):

  

生成的完全宏替换的预处理标记序列不会作为预处理指令处理,即使它类似于一个