-2

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

你看我正在用一种非常类似于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);
}
4

3 回答 3

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未定义。

于 2013-02-11T05:20:23.770 回答
0

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

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

由于您正在定义自己的语言,因此您会比我们更清楚它会如何反应!

于 2013-02-11T04:50:47.930 回答
0

关于您试图通过 实现的目标CONCAT,C99 标准的第 6.10.3.4 ¶3 节说(部分引用):

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

于 2013-02-11T04:52:34.120 回答