我一直在Java和VB.Net程序员约4年,约6个月,C#程序员。 我也用了一堆像Perl,Python和PHP和JavaScript动态语言。
我从来没有需要的预处理器。
我的问题是:为什么你看到C,使得大量使用预处理器,C ++和Objective-C,但很少(或从不)看到它像Java,C#或斯卡拉的语言吗?
我一直在Java和VB.Net程序员约4年,约6个月,C#程序员。 我也用了一堆像Perl,Python和PHP和JavaScript动态语言。
我从来没有需要的预处理器。
我的问题是:为什么你看到C,使得大量使用预处理器,C ++和Objective-C,但很少(或从不)看到它像Java,C#或斯卡拉的语言吗?
我不知道的Objective-C,所以我的答案是关于对比使用C和C预处理器++的。
预处理器最初是必要的下几个原因。 如果我没有记错,原本ç没有常数,所以#define
需要避免幻数。 此前1999 C没有内联函数,如此反复#define
用于创建宏或“伪功能”节省了函数调用的开销,同时保持代码的结构。 C也没有运行时或编译时多态,所以#ifdef
是需要条件编译秒。 编译器是典型的没有足够的智慧来优化掉可达代码,所以,再次#ifdef
小号被用来将调试或诊断代码。
使用C ++中的预处理器是倒退到C,并且在通常皱眉。 语言功能,如常量,内联函数和模板可以在大多数情况下使用用C你会使用预处理器。
在少数情况下,使用预处理器在C ++中的是可以接受的或甚至必要包括看守的头文件,以防止相同的报头被包括多次, #ifdef __cplusplus
使用相同的报头C和C ++ , __FILE__
和__LINE__
的记录,和其他几个人。
预处理器也经常用于特定于平台的定义,虽然C ++陷阱由Stephen杜赫斯特建议具有分离的包括用于特定于平台定义的目录,以及对每个单独的平台构建配置使用它们。
为什么你看不到的Java,C#或斯卡拉使用预处理的原因是,这些语言显然不具备的。
一个用于C预处理常见的用途是帮助提供特定于平台的代码。 由于C(我包括C ++和Objective-C在这里)是需要直接与操作系统的接口,可移植的代码也必然是编译为不同的操作系统代码的不同部分低层次的语言。 你可以在一个成熟的,高度可移植的代码库这样的事情的广泛例子,如zlib的 。
作为一个简单的例子,关闭网络套接字必须做这样的事情(在一定程度上,这当然可以被包裹在一个功能,但它有某处存在):
#ifdef WIN32
closesocket(s);
#else
close(s);
#endif
该虚拟机上运行的新的语言并不需要的代码不同的特定于平台的部分,并且可以针对单个便携式标准库编写。
预处理器还提供了一种在C中定义的常量,这是由其他更好的,语言功能在新的语言提供。
在设计C ++的演化和Bjarne的Stroustrup的说,他希望取消对C ++中的预处理器的依赖性,但没有成功。
每一种语言需要单独编制的机制。 理想情况下,语言区别于实现接口,以及模块只取决于它导出模块的接口。 (参见,例如,阿达,CLU,MODULA,等等。)
C具有的接口或实现无语言结构。 因为它是至关重要的,不同的.c文件共享接口的单一视图,编程学科发展投入声明(即接口)的.h文件和共享使用文本列入(这些声明/接口#include
)。 原则上, #define
和#ifdef
能够去掉,但#include
不能。
如今语言的设计者认识到,文本包含没有办法运行的铁路,所以语言往往运行要么单独编译接口(ADA,MODULA,OCaml中),编译器生成的接口(哈斯克尔),或对保证接口的一致性动态系统(Java,Smalltalk的)。 有了这样的机制,就没有必要对预处理器和大量的原因不能有一个(认为源代码分析和调试 )。
由于设计和这些语言的目的是不一样的。
下在头脑里的预处理器作为一个强大的工具来构建,它被用来实现非常基本的东西(如包括警卫)和开发人员能够用它来或者通过宏优化其代码或可选包含/排除的某些块代码除了其他事情。 C ++继承了大多数C的成语,宏不用于速度了(因为内嵌介绍),但它仍然用于很多事情,看后有什么预处理宏好?
因为高斯林和Heilsberg都了解其中的风险,并与预处理的误操作发生的技术债务!
我不同意什么,似乎是要达成共识,其中即CPP是联合国必要的现代语言。 我有很多在那里我有3个稍有不同版本的同一程序的情况下,我希望能够做一堆每个版本的变化。 随着CPP,我可以把他们都在#if #else伪块,我可以定义在编译行的#if。 在Java中,我需要建立某种形式的静态全局的,并在编译时初始化。 我从来没有说正常工作。
预处理是非常,在Java世界中非常普遍。 它被用来弥补语言的缺乏足够的内置的抽象能力,否则将导致无休止的复制和粘贴的样板代码。
许多人没有意识到这是真实的原因是,在Java世界中,它被称为“代码生成”而不是“预处理”,因为“预处理器”听起来就像讨厌的老C,而“代码生成”听起来像一个专业的工具, efficiates成熟的企业流程。 它仍然预处理,不过,即使你付出了一笔用于不兼容的非标准专有的工具来做到这一点,而不是仅仅使用语言内置的设施。
在C和C ++预处理器具有两种不同的功能
在构建过程中拉动文件一起 - 像Java等语言。 有自己的机制,例如做这个进口
执行文本替换 - 这仍需要一定程度上的C,而C ++可以做到这一点(在大多数情况下),更好的使用模板
所以C和C ++都需要它的第一项,但是C ++可以垃圾级到第二条,虽然它可以是即使在C ++中有用的-看到这个问题,从今天早些时候。
现代语言都包含在语言本身的预处理器! 对于C ++,只对模块管理和条件包含例如这是非常有用的所需的预处理器。
我相信这是一个单独的工具,因为编译器没有一个工具,我们今天知道他们。 听说用很旧的C编译器产生的令牌文件,然后执行编译的其余部分分离的阶段。 我能想到的最主要的原因是,相对于我们今天所拥有的内存和其他资源是非常稀缺。
可以肯定的是,现代的语言是用C或C ++,并在实现自身有宏。 你需要他们处理一件事操作系统的差异。 动态/高级语言包,并隐藏了许多在底部的地方,你需要的宏的事情。
此外,宏都用于转速的时候。 在动态语言,速度也不一样重要。
你应该看上去有点更加紧密的Perl的。 Perl的支持源过滤器 ,它们基本上是用Perl编写的定制Perl的预处理器:)
Java被设计避免了一些功能,使C ++很难使用。
C#复制(或继承)大部分从Java设计决定的。
高级编程语言避免这种低级别的文物。