Questions tagged «compiler»

编译器是一种计算机程序,可以将以一种编程语言编写的源代码转换为另一种计算机语言。

6
将基本类型(如int)实现为类的注意事项是什么?
设计和implenting面向对象的编程语言时,在某些时候你必须做出有关实现基本类型的选择(例如int,float,double或等价物)类或其他什么东西。显然,C系列语言倾向于不将其定义为类(Java具有特殊的原始类型,C#将其实现为不可变的结构,等等)。 当基本类型实现为类时(在具有统一层次结构的类型系统中),我可以想到一个非常重要的优势:这些类型可以是根类型的适当Liskov子类型。因此,我们避免使用装箱/拆箱(显式或隐式),包装器类型,特殊方差规则,特殊行为等使语言复杂化。 当然,我可以部分理解语言设计者为什么要决定他们的工作方式:类实例往往会有一些空间开销(因为实例可能在其内存布局中包含vtable或其他元数据),因此原语/结构不需要拥有(如果语言不允许继承这些语言)。 空间效率(以及改善的空间局部性,尤其是在大型阵列中)是基本类型通常不是类的唯一原因吗? 我通常认为答案是肯定的,但是编译器具有转义分析算法,因此当实例(任何实例,不仅仅是基本类型)被证明是严格的时,它们可以推断出是否可以(有选择地)忽略空间开销本地。 以上是错误的,还是我还缺少其他东西?

2
什么是ASM.js,对每个人意味着什么?
我开始听到有关这个名为ASM.js的项目的传闻。目前,他们的网站糟糕透顶。这是我在网络上的研究所知道的。 它是可以高度优化的JavaScript的子集。我猜是因为它避免了语言的动态部分。 编译为ASM.js的代码的性能大约是C的一半(不是很轻)。 目的是使编译器使其目标语言为ASM.js。 Firefox将随ASM.js优化一起发布。 Mozilla和Unreal团队通过它将Unreal Engine移植到了Web上,并以接近本地的速度运行在Firefox版本中。 网上似乎没有关于这到底是什么,有用性或最终目的的任何具体信息。是否可以编译本来可以在服务器端运行的代码库,并使其以接近本机的速度在浏览器中运行?对开发人员有什么影响?

5
C ++模板只是一种美化的宏吗?
通过C ++模板和C#/ Java泛型之间的不同比较,例如: /programming/31693/what-are-the-differences-between-generics-in-c-and-java-and-templates-in-c/31929#31929 我感觉到,C ++模板是通过某种预处理(在解析之前替换纯文本)而不是通过编译实现的。因为C ++模板中的类型检查类似于C宏。我的意思是,如果存在一些错误,它们是处理模板代码块后生成的代码中的错误,而不是模板本身中的错误。换句话说,它们只是C语言中宏的一种上层版本。 然后我发现了其他一些事实支持这一点- 我认为,如果C ++模板通过预处理实现,则动态链接(使用.dll)会出现问题。快速搜索支持了这一点。 另一点是,整数常量可以作为参数传递给模板。而且它甚至支持某种递归。但是在编译的汇编/机器代码中找不到此递归。通过为每个递归调用生成函数,可以在编译时管理递归对象,因此具有更大但更快的可执行二进制文件。 尽管与C宏不同,但它具有一些优越的功能。但是C ++模板不是通过某种预处理实现的吗?如何在不同的C ++编译器中实现?
27 c++  c  compiler  templates  macros 


2
Python(和其他动态语言)的哪些语义特征导致其缓慢?
我不太了解Python。我试图更精确地了解动态语言(如Python,Lua,Scheme,Perl,Ruby等)的确切功能正迫使他们的实现变慢。 作为一个例子,Lua 5.3的可继承机制会直观地使Lua变得很慢,但实际上有传言说Lua相当快(并且比Python快)。 另外,我有直觉(可能是错误的),由于目前的处理器内存大于原始计算慢得多(与高速缓存未命中的存储器访问需要的同时,数以百计的算术运算),动态类型检查(点菜if (value->type != INTEGER_TAG) return;的C语言)可以运行得很快。 当然,随着翻译程序的快速运行,整个程序分析(例如Stalin Scheme实现的工作)可以使动态语言实现成为可能,但是让我们假设我没有时间先设计整个程序分析器。 (我在MELT监视器中设计了一种动态语言,其中有些会翻译成C语言)

3
为什么没有针对本地机器代码的python编译器?
据我了解,造成编译语言与python之间速度差异的原因是,第一个方法将代码一直编译到本机计算机的代码,而python编译为python字节码,由PVM解释。我看到这种方式python代码可以在多个操作系统上使用(至少在大多数情况下),但是我不明白,为什么没有额外的(和可选的)python编译器,其编译方式与传统编译器相同。这将留给程序员选择,这对他们来说更重要。本机上的多平台可执行性或性能。一般来说; 为什么没有可以同时编译和解释的语言?

6
为什么将词法分析器实现为二维数组和巨型开关?
我正在慢慢地完成学业,这个学期是Compilers101。我们正在使用Dragon Book。在课程开始不久,我们将讨论词法分析以及如何通过确定性有限自动机(以下称DFA)来实现它。设置各种词法分析器状态,定义它们之间的过渡等。 但是教授和这本书都建议通过过渡表来实现它们,过渡表相当于一个巨大的2d数组(一个维的各种非终端状态,而另一个维可能的输入符号),以及一个用于处理所有终端的switch语句以及在非终端状态下调度到过渡表。 这个理论很好,但是作为一个几十年来实际编写代码的人,实现是不道德的。它不可测试,不可维护,不可读,调试起来很麻烦。更糟糕的是,如果该语言具有UTF功能,那么我将看不到它在远程实用。每个非终端状态都有一百万个左右的过渡表条目,这会很不方便。 那怎么办?为什么有关该主题的权威书籍说要这样做呢? 函数调用的开销真的那么多吗?当语法不为人所知时(正则表达式?),这是否行得通?也许可以处理所有情况的东西,即使更具体的解决方案更适合于更具体的语法? (注意:可能重复的“ 为什么使用OO方法而不是巨大的switch语句? ”已经很接近了,但我并不关心OO。使用功能性方法甚至具有独立功能的更明智的命令式方法都可以。) 并且为了示例,考虑一种仅具有标识符的语言,而这些标识符为[a-zA-Z]+。在DFA实施中,您将获得以下内容: private enum State { Error = -1, Start = 0, IdentifierInProgress = 1, IdentifierDone = 2 } private static State[][] transition = new State[][]{ ///* Start */ new State[]{ State.Error, State.Error (repeat until 'A'), State.IdentifierInProgress, ... ///* IdentifierInProgress */ new …

3
在哪个过程中发生语法错误?(标记或解析)
我正在尝试了解编译和解释,逐步找出总体图像。因此,在阅读http://www.cs.man.ac.uk/~pjj/farrell/comp3.html本文时,我遇到一个问题 它说 : 编译器的下一个阶段称为解析器。编译器的这一部分对语言的语法有所了解。它负责识别语法错误,并将无错误程序转换为可以用另一种语言解释或写出的内部数据结构。 但是我无法弄清楚令牌化器如何正确地令牌化具有语法错误的给定流。 它应该卡在此处或向解析器提供一些错误的信息。我的意思是标记化不是一种翻译器吗? 因此,它如何在标记化时克服了词汇中的错误代码行。 在Tokenizer标题上方的链接中有一个令牌示例。 据我了解,令牌的形式似乎是,如果代码中有错误,令牌也会被破坏。 您能澄清一下我的误会吗?

5
C编译器的历史是什么?
此问题是从Stack Overflow 迁移而来的,因为可以在Software Engineering Stack Exchange上回答。 迁移 8年前。 当我们说“ Dennis Ritchie开发了C语言”时,是否表示他已经创建了一个编译器(使用“已经”开发的其他语言)来编译用C语言编写的源代码?如果是,他用来编写第一个C编译器的语言是什么?我知道编译器是一个程序,我们可以使用当前可用的C编译器为C语言创建另一个编译器。那是对的吗?
23 c  compiler 

6
编译器静态类型检查“复杂”表达式时,常用的程序是什么?
注意:在标题中使用“复杂”时,是指该表达式具有许多运算符和操作数。表达式本身并不复杂。 我最近一直在研究一个简单的x86-64汇编程序。我已经完成了编译器的主要前端-词法分析器和解析器-现在可以生成程序的抽象语法树表示形式。由于我的语言将是静态类型的,因此我现在进入下一阶段:类型检查源代码。但是,我遇到了一个问题,而自己却无法合理解决。 考虑以下示例: 我的编译器的解析器已阅读以下代码行: int a = 1 + 2 - 3 * 4 - 5 并将其转换为以下AST: = / \ a(int) \ - / \ - 5 / \ + * / \ / \ 1 2 3 4 现在,它必须键入检查AST。首先检查=操作员的类型。首先检查操作员的左侧。可以看到该变量a被声明为整数。因此,它现在必须验证右侧表达式为整数。 我了解如果表达式只是一个值(例如1或),该怎么办'a'?但是,对于具有多个值和操作数的表达式(一个复杂的表达式)(例如上述表达式),该如何处理呢?为了正确确定表达式的值,似乎类型检查器实际上必须执行表达式本身并记录结果。但这显然似乎破坏了将编译和执行阶段分开的目的。 我想可以做到的唯一另一种方法是递归检查AST中每个子表达式的叶子,并验证所有叶子的类型都与期望的运算符类型匹配。因此,从=运算符开始,类型检查器将扫描左侧的所有AST并验证叶子都是整数。然后,它将对子表达式中的每个运算符重复此操作。 我曾尝试在《龙书》的副本中研究该主题,但似乎没有涉及太多细节,只是重申了我已经知道的内容。 当编译器对具有多个运算符和操作数的表达式进行类型检查时,通常使用的方法是什么?我上面提到的任何方法都使用吗?如果没有,那么方法是什么,它们将如何工作?

1
为什么某些语言的文档说“等于”而不是“是”?
为什么某些语言的文档说“等于”而不是“是”? 例如,Python文档说 itertools.chain(*iterables) ... 等效于: def chain(*iterables): # chain('ABC', 'DEF') --> A B C D E F for it in iterables: for element in it: yield element 或者,这个C ++参考的find_if: 该功能模板的行为等效于: template<class InputIterator, class UnaryPredicate> InputIterator find_if (InputIterator first, InputIterator last, UnaryPredicate pred) { while (first!=last) { if (pred(*first)) return first; …

2
是否可以创建独立于原始解释程序的“自举”解释程序?
根据Wikipedia的说法,在编写编译器的上下文中,“引导”一词的含义是: 在计算机科学中,引导程序是使用要编译的源编程语言编写编译器(或汇编器)的过程。应用此技术将导致自托管编译器。 我可以理解这将如何工作。但是,对于口译员来说,故事似乎有些不同。现在,当然可以编写自托管解释器了。那不是我要的 我实际上要问的是:是否可以使自托管翻译器独立于原始的第一翻译器。为了解释我的意思,请考虑以下示例: 你写在你的语言翻译的第一版本X和解释是为正在创建一个新的语言,称为ÿ。首先,您使用X语言的编译器来创建可执行文件。现在,您可以使用以语言X编写的解释器来解释以您的新语言Y编写的文件。 现在,据我所知,要能够“引导”您使用语言X编写的解释器,您需要使用语言Y重写该解释器。但这很重要:即使您确实使用语言Y重写了整个解释器,仍然需要使用语言X编写的原始解释器。因为要使用语言Y运行解释器,所以您将不得不解释源文件。但是,究竟该如何解释源文件呢?好吧,当然不能没有什么,所以您被迫仍然使用第一个解释器。 不管您用语言Y编写了多少新的解释器,您始终将必须使用用X编写的第一个解释器来解释后续的解释器。仅仅由于口译员的性质,这似乎是一个问题。 但是,另一方面,这篇关于口译员的Wikipedia文章实际上讨论的是自托管口译员。这是一个相关的小摘录: 自解释器是用一种可以解释自身的编程语言编写的编程语言解释器;一个例子是用BASIC编写的BASIC解释器。自解释器与自托管编译器有关。 如果不存在用于要解释的语言的编译器,则创建自解释器需要使用宿主语言(可以是另一种编程语言或汇编程序)来实现该语言。通过拥有这样的第一个解释器,系统将被引导,并且可以使用语言本身开发新版本的解释器 不过,对于我来说仍然不清楚如何完成此操作。看来,无论如何,您总是被迫使用以宿主语言编写的解释器的第一个版本。 现在,上面提到的文章链接到另一篇文章,其中Wikipedia提供了一些假定的自我托管解释器的示例。经过仔细检查,似乎许多这些自托管解释器(尤其是一些较常见的解释器,例如PyPy或Rubinius)的主要“解释”部分实际上是用其他语言编写的,例如C ++或C。 那我上面描述的可能吗?自托管口译员可以独立于其原始主机吗?如果是这样,将如何精确地做到这一点?

4
GCC vs clang / LLVM —各自的优缺点
按照目前的情况,这个问题不适合我们的问答形式。我们希望答案会得到事实,参考或专业知识的支持,但是这个问题可能会引起辩论,争论,民意调查或扩展讨论。如果您认为此问题可以解决并且可以重新提出,请访问帮助中心以获取指导。 6年前关闭。 GCC与clang / LLVM的优缺点是什么?
20 compiler  clang  gcc  llvm 

6
何时支付C ++编译器费用[关闭]
已关闭。这个问题是基于观点的。它当前不接受答案。 想改善这个问题吗?更新问题,以便通过编辑此帖子以事实和引用的形式回答。 5年前关闭。 最近,我开始怀疑开发人员何时应该为编译器付费。大多数平台都免费提供编译器,或者容易获得免费版本。 例: OS X-开发人员工具随附GCC和Clang / LLVM。对于如何使用它们以及在其中得到什么,这里没有任何限制。 Linux-GCC,我敢肯定。我不知道linux编译器的当前状态。对于如何使用它们以及在其中得到什么,这里没有任何限制。 Windows-MinGW和Microsoft确实提供了Visual Studio的免费版本。MinGW没有任何限制,但我认为免费的Visual Studio存在严重的限制。 但是,例如,英特尔生产C / C ++编译器。他们的价格很高。在教育方面,我认为可以以49美元的价格获得OS X版本,以129美元的价格获得Windows / Linux。然后,他们也提供完整的“ Studio”产品。显然,使用教育定价会受到限制。 但是我想知道的是,何时应该真正考虑为编译器付费。我能想到的一个例子是电子游戏。如果您使用的是可在主要平台上运行的编译器,则该平台将不再有切换工具。如果工具相同,在平台之间切换似乎会很容易。 任何人都可以在支付诸如英特尔编译器之类的编译器费用方面获得一些启示,以及使用它们可能获得的真正的跨平台收益吗?即使非常努力地不使用平台特定的技术,代码的可移植性也会降低吗?
19 c++  compiler 


By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.