const против enum в D - PullRequest
       40

const против enum в D

6 голосов
/ 04 марта 2009

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

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

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

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

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

Ответы [ 5 ]

4 голосов
/ 04 марта 2009

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

4 голосов
/ 04 марта 2009

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

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

enum int a = 10; // new in D2

Это как

enum : int { a = 10 }

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

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

3 голосов
/ 04 марта 2009

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

2 голосов
/ 04 марта 2009

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

1 голос
/ 04 марта 2009

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

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

...