C宏能改变宏关键字吗?

3

宏可以轻松地为C语言中的关键字设置别名,但它是否可以用于更改宏关键字呢?这样,就不需要写:

#include <stdlib.h>

#define se if

有人可能会写

#inkludu <stdlib.h>

#difinu se if

换句话说,预处理指令能否被设置别名,最好不需要修改代码本身,例如通过编译器参数(如gcc中的-D)来实现。
以下简单测试将失败:
#define difinu define
#difinu valoro 2

int main() {
    int aĵo = valoro;
    return 0;
}

以下是出现的错误:

 % clang makro.c -o makro
makro.c:2:2: error: invalid preprocessing directive
#difinu valoro 2
 ^
makro.c:5:16: error: use of undeclared identifier 'valoro'
    int aĵo = valoro;
              ^
2 errors generated.

1
你试过了吗?请在C和C++中选择一种语言,这两种语言不相等,它们的预处理器也不相等。 - fuz
不可以使用预处理器来改变预处理器和语言语法的工作方式。 - Shark
好的,我已经添加了我尝试过的文档,并将问题限制在C语言范围内(尽管C++解决方案对我也很有兴趣)。 - psychoslave
你到底想通过将整个C语言翻译成世界语来实现什么? - Lightness Races in Orbit
正如下面建议的,长期来看,拥有一个专用的语言确实更有意义,并具有自托管等功能。特别是在其设计中可以至少部分地依赖于世界语的常规语法。我会尽可能多地使用世界语。此外,我的目标是使用完整准确的单词,而不是缩写和其他非字母符号。也许这并不是普遍共享的愿望,但这将使我能够按照自己的喜好编写代码。 - psychoslave
4个回答

6
不,宏并不会改变预处理指令的处理方式(但当然可以根据条件指令(如#if)进行更改)。特别是,以下内容是错误的。
///WRONG CODE
#define inc include
/// the following directive is not recognized as an include
#inc <stdio.h>

顺便提一句,拥有

#define se if

即使可能,注释代码真的是一个不好的习惯。它会使您的代码 se (x>0) {printf("negative x=%d\n", x);} 更难阅读。

考虑使用一些 其他 预处理器(如m4GPP)对源代码进行预处理。这相当于从其他东西生成您的C(或C ++)代码。

我的感觉是元编程通常是个好主意:你编写一个专门的程序,可以发出C或C++代码(并相应地改进构建过程,例如您的Makefile)。但是你可能会设计一个真正的C或C++代码生成器(它将在某种AST上工作和处理)。解析器生成器(错误地称为编译器编译器)如ANTLRbison是一个很好的例子。而Qt有moc

相关问题的答案请参考thisthat

在尝试编写自己的代码生成器(或领域特定语言实现)之前,请不要忘记阅读多本教科书(特别是与编译器相关的教科书)。


这类似于 #define TRUE 0 #define FALSE 1 - Shark
我之前不知道GPP,它似乎非常适合我正在做的事情。这只是使用世界语关键字翻译C语言,没有进行语法修改。谢谢。因此,对于这个特定项目,将“se”作为条件语句是有意义的。 - psychoslave
1
但是这样做真的是一个坏主意。你希望C代码能够被全世界的其他开发人员阅读。仅仅将关键字翻译成世界语只会让人感到困惑,而且没有任何价值。如果你坚持要用世界语关键字创建一种编程语言,那么请设计并实现自己的编程语言(并使其比C更好)。 - Basile Starynkevitch
1
我同意这不是一个好的自我维持目标。然而,对我来说,制作这种项目似乎是学习哪些词汇可能有用,以及在设计和实现更原创的编程语言方面有用的概念的好方法。谢谢你的建议。 - psychoslave
然后,你的方法会浪费很多时间。最好开始设计和实现你的“更好的世界语式”编程语言,并逐步添加功能。阅读我提到的其他答案中给出的参考资料。 - Basile Starynkevitch

2

历史上有些编译器可以重新定义宏定义,需要注意的是,IOCCC 1985中的以下条目证明了这一点。在当时的Vax 780/4.2BSD上,该条目显然可以成功编译:

http://ioccc.org/1985/lycklama/lycklama.c

该条目开头如下:

#define o define
#o ___o write
#o ooo (unsigned)

我喜欢IOCCC被作为已经可能的示例之一。从未想过这样。 - Tim
这比我们今天定义的“C”更早。 - Lightness Races in Orbit

0
"

"#define" 是预处理器中用于编译/编译器的“宏替换(文本替换)”的关键字。在C语言的代码编译阶段中,考虑到“预处理器->编译器->汇编器->链接器->加载器”的顺序。

因此,当您编译此代码时,预处理器会尝试搜索不存在的关键字“#difinu”,因此您会从预处理器阶段获得错误。

此外,“#define”是单个关键字,您如何期望预处理器将其视为“#”+“define”。例如:

"
#define game olympic 
main (){
 int abcgame =10;// will it become "abcolympic" ??
 return;
}

0

本地化语言确实存在。Algol68(在Linux下可用)是一种非常古老的语言(1968年),顺便说一下,它是现存最优秀的语言之一:

IF x < y THEN x ELSE y FI := 3;
( x < y | x | y ) := 3;
IF x < y THEN sin ELSE cos FI(3.14)

在您的情况下,我会编写一个额外的预处理器,例如 .eocpp 和 .eohpp 转换为 .cpp 和 .hpp。它可以进行特殊字符的转换,甚至是字典翻译。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接