Вопрос

Посмотрите эту цитату из здесь, в нижней части страницы.(Я верю цитированному комментарию о constэто относится к invariants тоже)

Перечисления отличаются от Consts тем, что они не потребляют места в конечном выведении объекта/библиотеки/исполняемого, тогда как Consts делают.

Так что, видимо value1 будет раздувать исполняемый файл, в то время как value2 рассматривается как литерал и не отображается в объектном файле.

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

Возвращаясь к C++, я всегда предполагал, что это происходит по причинам, связанным с устаревшими версиями, и старыми компиляторами, которые не могли оптимизировать константы.Но если это все еще верно для D, то за этим должна быть более глубокая причина.Кто-нибудь знает, почему?

Это было полезно?

Решение

Как и в C++, перечисление в D выглядит как «консервативный целочисленный литерал» (редактировать:потрясающе, D2 даже поддерживает поплавки и строки).Его счетчики не имеют местоположения.Они просто нематериальны как ценности без идентичности.

Размещение enum является новым в D2.Сначала он определяет новую переменную.Это не lvalue (поэтому вы также не можете получить его адрес).Ан

enum int a = 10; // new in D2

Как

enum : int { a = 10 }

Могу ли я доверять своим плохим знаниям D.Так, a здесь нет lvalue (нет местоположения, и вы не можете получить его адрес).Константа, однако имеет адрес.Если у вас есть глобальная константная переменная (не уверен, что это правильная терминология D), компилятор обычно не может ее оптимизировать, потому что он не знает, какие модули могут получить доступ к этой переменной или могут получить ее адрес.Поэтому для него необходимо выделить место для хранения.

Я думаю, что если у вас есть локальная константа, компилятор все равно может ее оптимизировать, как и в C++, потому что, просматривая ее область видимости, компилятор знает, заинтересован ли кто-нибудь в ее адресе или все просто принимают ее значение.

Другие советы

Ваш актуальный вопрос;почему enum/const в D один и тот же, что и в C++;кажется, остался без ответа.К сожалению, нет никаких веских причин для такого выбора.Я считаю, что это был просто непреднамеренный побочный эффект в C++, который де-факто стал шаблоном.В D нужна была та же самая схема, и Уолтер Брайт решил, что нужно сделать как в C++, чтобы пришедшие из этого места понимали, что делать...Фактически, до этого, по моему мнению, довольно глупого решения, для этого варианта использования вместо enum использовалось ключевое слово манифест.

Я думаю, что хороший компилятор/компоновщик все равно должен удалить константу.Просто перечисление фактически гарантировано в спецификации.Разница в первую очередь заключается в семантике.(Также имейте в виду, что версия 2.0 еще не завершена)

Истинная цель enum Синтаксическое расширение для поддержки одиночных констант манифеста, насколько я понимаю, заключается в том, что Дон Клагстон, гуру шаблонов D, делал какие-то сумасшедшие вещи с шаблонами.Он продолжал сталкиваться с длительным временем сборки, нелепым использованием памяти компилятора и т. д.потому что компилятор продолжал создавать внутренние структуры данных для константных переменных.Одна из ключевых особенностей константных/неизменяемых переменных по сравнению с перечислениями заключается в том, что константные/неизменяемые переменные являются lvalue и могут иметь свой адрес.Это означает, что для компилятора требуются дополнительные накладные расходы.Обычно это не имеет значения, но когда вы выполняете действительно сложные метапрограммы времени компиляции, даже если константные переменные оптимизированы, это все равно приводит к значительным накладным расходам во время компиляции.

Похоже, что значение перечисления будет использоваться «встроено» в выражениях, где константа фактически будет занимать хранилище, и любое выражение, ссылающееся на него, будет загружать значение из хранилища памяти.

Этот звук похож на разницу между const и.только для чтения в C#.Первая является константой времени компиляции, а вторая — константой времени выполнения.Это определенно повлияло на управление версиями сборок (поскольку сборки, ссылающиеся на сборку только для чтения, получали копию во время компиляции и не получали изменения значения, если ссылочная сборка была перестроена с другим значением).

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top