为什么大多数现代编程语言中都不包含宏?

我认识到它们在C / C ++中的应用异常不安全。 它们不能以更安全的方式应用吗? 宏的负面影响实际上是否足以超越它们给予的实质性力量?

0
2019-05-04 17:46:44
资源 分享
答案: 5

我实际看到的宏最大的麻烦是,当它被大量使用时,它们可以使代码真的难以理解,并且还可以保留它们允许你隐藏宏中可能或可能不容易定位的推理(也可能或者可能不是不重要的)。

0
2019-05-08 04:43:59
资源

宏可以,斯科特指出,允许您隐藏推理。 当然,功能,课程,收藏以及其他几种常用工具也是如此。

然而,一个有效的宏系统可以变得更好,允许您制作并使用语法以及通常不在语言中的框架。 毫无疑问,这可以是一个非凡的设备:特定领域的语言,代码生成器,甚至更多,所有这些都在一个单独的语言设置的方便...

但是,它可能被滥用。 它可以使代码更难以阅读,识别和调试,增加新设计师习惯于代码库所必需的时刻,同时也带来了昂贵的错误和挫折。

所以对于计划的语言 精简 显示(像Java或Python),这样的系统是一个禁忌。

0
2019-05-08 04:32:59
资源

为了解决您的问题,请考虑主要使用的宏(警告:脑编译代码)。

  • 宏使用来指定符号常量#define X 100

这可以通过以下方式方便地更改:const int X = 100;

  • 宏使用来指定(基本上)内联类型不可知的特征#define max(X,Y) (X>Y?X:Y)

在任何支持函数重载的语言中,这可以通过实际紧张的特征类型,或者用支持泛型的语言,通过一个共同的函数,以更加类型安全的方式模仿。 宏将很乐意尝试对比 什么 由提醒或字符串组成,可以编译,但可能不是你想要的。 另一方面,如果您使宏类型安全,它们没有优势或轻松超载功能。

  • 宏使用它来定义常用组件的更快方法。 #define p printf

这可以通过函数p()方便地更改,该函数执行相同的操作。 这与C(需要你使用va_arg()系列特征成员)相关联,但在几种其他支持各种功能争论的语言中,它的复杂程度要低得多。

保持这些属性 与独特的宏语言相对的语言不那么复杂,更容易出错,而且对于审阅代码的其他人来说也简单得多。 实际上,我不能考虑一个 用例宏用于无法通过其他方式方便地复制的宏。 该 只要 宏是绝对有价值的区域是它们链接到条件集合结构,如#if(等)。

关于这一特定因素,我不会跟你说,因为我认为非预处理器补救首选语言中的条件集合非常困难(比如Java中的字节码)。 然而,像D这样的语言实际上已经考虑过不需要预处理器的补救措施,并且比使用预处理器条件更难以消除,同时更不容易出错。

0
2019-05-08 04:07:34
资源

我假设主要因素是宏 词法 。 这有很多影响:

  • 编译器没有其他方法可以检查宏在语义上是否关闭,即它代表一个“定义设备”,就像函数一样。 (考虑#define TWO 1+1-- TWO*TWO相当于什么?3。)

  • 宏没有键入功能。 编译器无法检查参数和返回类型是否有意义。 它可以只检查使用宏的增加的表达式。

  • 如果代码没有编译,编译器没有其他方法可以识别错误是保留在宏本身还是宏使用的区域。 编译器当然会在50%的时间内报告错误的区域,或者它需要报告两者,尽管它们之间可能很好。 (考虑#define min(x,y) (((x)<(y))?(x):(y)):如果xy的类型不匹配或者没有实现operator<,编译器应该怎么做?)

  • 自动化设备无法以语义上有价值的方式与它们协作。 具体来说,您不能像IntelliSense这样的点用于功能类似功能但扩展到表达式的宏。 (再次,min实例。)

  • 宏的副作用并不像特征那样具体,为设计师带来了可能的复杂性。 (再次考虑min实例:在函数调用中,您认识到x的表达式会被立即检查,但是如果不考虑宏,则无法识别。)

就像我声称的那样,这些都是宏观词汇现实的影响。 当你试图将它们转换成额外正确的东西时,你最终会得到特征和常量。

0
2019-05-08 03:59:10
资源

但当然是宏 能够 制作并应用得比C / C ++好得多。

宏的问题在于它们是正确的 语言语法扩展 将代码修改为其他内容的设备。

  • 在C / C ++实例中,没有基本的安心监控。 如果你小心,分数是正确的。 如果你滑倒,或者你过度使用宏,你可能会遇到大麻烦。

    其中包括您可以使用各种其他语言以各种其他方法执行的几个简单的(C / C ++设计)宏。

  • 在诸如众多Lisp语言之类的各种其他语言中,宏与核心语言语法更好地结合在一起,但是在宏观“滴落”中你仍然会遇到麻烦。 这由卫生的宏解决。


快速历史背景

宏(宏指令简介)首先出现在设置语言的上下文中。 根据维基百科,在20世纪50年代,一些IBM汇编程序中可以使用宏。

最初的LISP确实没有宏,但它们在20世纪60年代中期首次出现在MacLisp中:https://stackoverflow.com/questions/3065606/when-did-the-idea-of-macros-user-defined-code-transformation-appearhttp://www.csee.umbc.edu/courses/331/resources/papers/Evolution-of-Lisp.pdf。 在此之前,“fexprs”具有宏观能力。

C的最早变体确实没有宏(http://cm.bell-labs.com/cm/cs/who/dmr/chist.html)。 这些包括大约1972-73使用预处理器。 在此之前,C只是持续了#include#define

M4宏预处理器来自大约1977年。

额外的当前语言显然实现了宏,其中过程的版本是语法而不是文本。

所以,当一个人谈论 首位 对于“宏观”一词的某种定义,有必要记住,该定义实际上随着时间的推移而提前。

0
2019-05-08 02:07:26
资源