1
13
我不知道Objto-C,所以我的答案是对比C和C++中预处理器的使用情况。 预处理器最初是C所必需的,原因有几个。如果我没记错的话,原来c没有常量,所以需要定义来避免使用幻数。在1999年之前,C没有内联函数,因此再次使用define创建宏或“伪函数”,以节省函数调用的开销,同时保持代码的结构化。C也没有运行时或编译时多态性,因此条件编译需要ifdefs。编译器通常不够智能,无法优化无法访问的代码,因此,再次使用ifdefs插入调试或诊断代码。 使用C++中的预处理器是对C的一种回退,通常是不赞成的。语言特性,例如常量、内联函数和模板,可以在大多数情况下使用,在C中,您可以使用预处理器。
在C++中使用预处理器是可接受的,甚至是必要的几个情况下,包括头文件的防护,以防止同一个报头被多次包含,
预处理器也经常用于特定于平台的定义,尽管 C++ Gotchas StephenDewhurst建议为平台特定的定义提供单独的include目录,并在每个平台的单独构建配置中使用它们。 |
2
10
C预处理器的一个常见用途是帮助提供特定于平台的代码。由于C(我这里包含C++和ObjuleC)是一种低级语言,它需要直接与操作系统接口,在便携代码中,必须为不同操作系统编译的代码的不同部分。您可以在一个成熟的、高度可移植的代码库中找到这类事情的大量示例,例如 zlib . 作为一个简单的例子,要关闭一个网络套接字,必须这样做(在某种程度上,这当然可以包装在一个函数中,但它必须存在于某个地方):
在虚拟机上运行的新语言不需要不同平台特定的代码部分,并且可以针对单个可移植标准库编写。 预处理器还提供了一种在C中定义常量的方法,这些常量由更新语言中的其他更好的语言功能提供。 在C++的设计和进化中,Bjarne Stroustrup表示他想删除C++中预处理器的依赖性,但没有成功。 |
3
9
每种语言都需要一种机制 单独汇编 . 理想情况下,语言将接口与实现区分开来,并且模块仅依赖于其导出的模块的接口。(请参见,例如ADA、CLU、MODULA等。)
C没有接口或实现的语言结构。因为不同的.c文件共享接口的单一视图是至关重要的,所以编程规则演变为将声明(即接口)放入.h文件并使用文本包含方式共享这些声明/接口。(
现在,语言设计者认识到文本包含是不可能运行一条铁路的,所以语言倾向于运行到单独编译的接口(艾达,Modula,OCAML),到编译器生成的接口(Haskell),或者到保证接口一致性的动态系统(Java,SimalTalk)。有了这样一种机制,就不需要预处理器,而且有很多理由不需要预处理器(想想 源代码分析 和 调试 ) |
4
4
因为这些语言的设计和目标不一样。 C是在预处理器的基础上构建的,作为一个强大的工具,它被用来实现非常基础的东西(比如包含保护),开发人员可以使用它来优化他们的代码,或者选择包括/排除某些代码块以及其他东西。 C++继承了大多数C的成语,宏不再用于速度(因为内联被引入),但它仍然用于大量的事物,参见文章。 What are preprocessor macros good for? |
5
3
因为戈斯林和海尔斯堡都明白错误的预处理带来的危险和技术债务! |
6
1
C和C++中的预处理器有两个不同的功能
所以C和C++都需要第一个,但是C++可以把它放在第二个,尽管它在C++中也是有用的。 this question 从今天早些时候开始。 |
7
1
我不同意目前的共识,即CPP在现代语言中是不必要的。我有很多情况下,我有3个稍微不同版本的同一个程序,我想能够作出一系列的改变,为每个版本。使用cpp,我可以将它们全部放在if-else块中,并且可以在编译行定义if。在爪哇中,我需要创建一些静态全局,并在编译时初始化它。我从来没有把它做好。 |
8
1
现代语言本身就包含了预处理器!对于C++,预处理只需要用于模块管理和条件包含,例如非常有用。 我相信它是一个独立的工具,因为编译器不是我们今天所知道的一个工具。我听说非常老的C编译器用于生成文件的令牌,然后在不同的阶段进行其余的编译。我能想到的主要原因是,与我们今天拥有的相比,记忆和其他资源非常稀缺。 |
9
1
在Java世界中,预处理是非常常见的。它用于补偿语言缺乏足够的内置抽象设施,否则将导致无休止的复制和粘贴样板代码。 许多人没有意识到这一点是正确的,在Java世界中,它被称为“代码生成”而不是“预处理”,因为“预处理器”听起来像讨厌的老C,而“代码生成”听起来像是一种专业工具,它能有效地提高成熟的企业流程。尽管如此,它仍然是预处理的,即使你必须为一个不兼容的非标准专有工具支付一大笔钱,而不仅仅是使用语言中内置的工具。 |
10
0
可以肯定的是,现代语言是用C或C++编写的,而在实现本身中也有宏。您需要他们处理操作系统差异,一方面。动态/高级语言包装并隐藏了许多底层需要宏的东西。 此外,宏有时也用于速度。在动态语言中,速度并没有那么重要。 |
11
0
您应该更仔细地看一下Perl。Perl支持 source filters ,基本上是用Perl编写的自定义Perl预处理器:) |
12
0
Java是为了避免一些使C++难以使用的特性而设计的。 复制或继承大部分来自Java的设计决策。 高级编程语言避免了这种低级的工件。 |
Imad Hamaidi · 如何使预处理器宏在编译之前对代码求值 2 年前 |
R overflow · R以每行一个字符串的方式粘贴输入 6 年前 |
pasha · C++:宏参数中可以有空格吗? 6 年前 |
Zorglub29 · 使用宏显示宏的字符串化内容 6 年前 |
Detonar · 检查预处理器符号(#define)的值 6 年前 |
СеÑгей · MinGW中预处理器g++的奇怪行为 6 年前 |