Optimization D中的常量与枚举

Optimization D中的常量与枚举,optimization,enums,constants,d,Optimization,Enums,Constants,D,查看这段引语,从,到页面底部。(我相信引用的关于consts的评论也适用于invariants) 枚举与常量的不同之处在于它们不占用任何空间 在最终输出的对象/库/可执行文件中,而常量则是 因此,value1显然会使可执行文件膨胀,而value2被视为文本,不会出现在对象文件中 const int value1 = 0xBAD; enum int value2 = 42; 在C++中,我总是假设这是遗留的原因,而旧编译器不能优化常量。但如果这在D中仍然是正确的,那么这背后一定有更深层次的原因。

查看这段引语,从,到页面底部。(我相信引用的关于
const
s的评论也适用于
invariant
s)

枚举与常量的不同之处在于它们不占用任何空间 在最终输出的对象/库/可执行文件中,而常量则是

因此,
value1
显然会使可执行文件膨胀,而
value2
被视为文本,不会出现在对象文件中

const int value1 = 0xBAD;
enum int value2 = 42;

在C++中,我总是假设这是遗留的原因,而旧编译器不能优化常量。但如果这在D中仍然是正确的,那么这背后一定有更深层次的原因。有人知道为什么吗?

听起来枚举值将在表达式中“内联”使用,其中as const将实际占用存储空间,任何引用它的表达式都将从内存中加载值


这听起来类似于C#中const与readonly之间的区别。前者是编译时常量,后者是运行时常量。这肯定会影响程序集的版本控制(因为引用只读的程序集将在编译时收到一个副本,并且如果引用的程序集是用不同的值重新生成的,则不会对该值进行更改)。

我认为一个好的编译器/链接器仍然应该删除该常量。只是对于枚举,它实际上在规范中得到了保证。区别主要是语义问题。(也请记住,2还没有完成)

< P>就像C++一样,D中的枚举似乎是一个“保守的整数文字”(<强>编辑< /强>:惊人,D2甚至支持)。它的枚举数没有位置。作为没有身份的价值观,它们只是无关紧要的

放置
enum
在D2中是新的。它首先定义一个新变量。它不是左值(因此您也不能获取它的地址)。一个

就像

enum : int { a = 10 }
如果我能相信我贫乏的知识。因此,
a
在这里不是左值(没有位置,您不能获取它的地址)。然而,const有一个地址。如果您有一个全局(不确定这是否是正确的D术语)常量变量,编译器通常无法对其进行优化,因为它不知道哪些模块可以访问该变量或获取其地址。因此,它必须为其分配存储空间


我认为如果你有一个本地const,编译器仍然可以像C++一样优化它,因为编译器通过查看它的范围来知道是否有人对它的地址感兴趣或者是否每个人都在它的值。p> 你的实际问题;为什么在C++中,EnUM/const与D是相同的;似乎没有答案。遗憾的是,这种选择没有任何好的理由。我相信这只是C++中的一种无意的副作用,它变成了阿德的事实模式。在D中,同样的模式是需要的,Walter Bright决定应该像C++那样做,这样来自那个地方的人会知道该怎么做…事实上,在这个相当愚蠢的决定之前,在这个用例中使用了关键字manifest而不是enum。

enum
进行语法扩展以支持单个manifest常量的真正目的,据我所知,是D模板大师Don Clugston对模板做了一些疯狂的事情。由于编译器不断地为常量变量创建内部数据结构,他一直在运行长时间的构建、荒谬的编译器内存使用等。与enum相比,const/不可变变量的一个关键点是,const/不可变变量是左值,可以使用它们的地址。这意味着编译器会有一些额外的开销。这通常无关紧要,但当您执行非常复杂的编译时元程序时,即使常量变量被优化了,这在编译时仍然是很大的开销。

但这一愿望假设编译器始终拥有所有相关的源代码。如果您想让第三方库访问该常量变量,该怎么办?如果它是一个被设置为const的整个类实例呢?注意我说的是“compiler/*linker*”。此外,D无论如何都必须能够在编译时看到变量的值(对于常数折叠和其他事情),因此物理地将它存储在某个地方就没有什么意义了——任何需要它的情况都需要可用的源代码。(我不知道有任何编译器在内部从早期运行中反汇编目标代码)不幸的是
enum
意味着manifest常量。然而,D只指出改变明确被破坏的东西,其他一切都遵循algol语言的既定规范。我相信如果你真的全力以赴,你会发现很多奇怪的关键字和语法,它们本可以做得更好,比如赋值/相等,返回值列在函数名之前,结构/聚合,等等。
enum : int { a = 10 }