#terminology #d #compile-time #declarative #static-if
#терминология #d #время компиляции #декларативный #статическое-если
Вопрос:
Рассмотрим следующий код:
static if (!is(MyStruct))
{
struct MyStruct
{
}
}
static if (is(MyStruct))
{
static assert(0);
}
Мое первоначальное понимание заключалось в том, что порядок объявлений (в глобальном масштабе) не имеет значения в D.
Однако в этом случае порядок static if
s определяет, компилируется программа или нет.
Следовательно, является ли этап оценки D во время компиляции процедурной функцией (например, C / C ), декларативной функцией или чем-то еще? Что это такое в настоящее время и каким оно планируется (если они разные)?
Редактировать:
Я только что понял, что проблема на этом даже не заканчивается. Что происходит с static if
использованием .tupleof
a для перечисления членов текущего модуля и создания проблемы того же типа?
Ответ №1:
Это декларативная функция, которая обладает процедурными свойствами в качестве побочного эффекта реализации.
Комментарии:
1. Я думаю, что были некоторые разговоры о том, чтобы сделать этот пример кода незаконным. Либо отклоняя его напрямую, либо объявляя его неопределенным поведением.
2. @BCS: Разве это невозможно обнаружить? По крайней мере, когда в игру вступают микшины, это похоже на проблему остановки….
3. @Mehrdad Не обязательно, особенно в обычных случаях. Одним из подходов было бы иметь
is()
«ловушку-ловушку» в таблице символов, а затем считать ошибкой вставку символа, который изменил бы значение уже оцененногоstatic if
4. @BCS: Как бы это работало правильно, если бы два модуля имели перекрестные зависимости, и они оба проверяли типы друг друга? Какой из них первый? Должно ли это быть важным? Должен ли кто-то иметь возможность блокировать компиляцию другого?
5. @Mehrdad: нахождение в разных модулях не имеет значения, код OP иллюстрирует суть: скажем
if
, сначала запускается второй, он ничего не делает, а затемif
запускается первый, «захватывает» символMyStruct
, а затем пытается добавить это простое отключение ловушки и выдает сообщение об ошибке. Если все происходит по-другому, выдается то же сообщение об ошибке, даже не доходя до 2-гоif
. — OTOH это работает, делая самую полезную версию проблемы незаконной.
Ответ №2:
Это усложняется. По сути, это декларативно, но порядок все равно может иметь значение, когда a static if
вводит новый символ. Помимо этого, я не верю, что это когда-либо имеет значение, но, как показывает ваш пример, когда вы вводите новый символ в a static if
, а другой static if
использует его, порядок определенно может иметь значение.
Недавно было некоторое обсуждение того, как сделать его максимально последовательным и интуитивно понятным. Таким образом, особенно в угловых случаях, ситуация может измениться в ближайшем будущем. Но я бы ожидал, что ваш пример продолжит вызывать static assert
. Вопрос в том, начнет ли он запускаться static assert
, если вы измените порядок static if
блоков, и я не уверен, что это действительно было решено. Обсуждение этого в группе новостей компилятора не совсем убедительно и немного сложно следовать ИМХО, поэтому я не могу сказать наверняка. Но я ожидаю, что упорядочение по-прежнему будет иметь значение, по крайней мере, в некоторых случаях, static if
когда блок вводит новый символ.
Редактировать:
Это было недавно опубликовано одним из основных участников dmd:
В настоящее время порядок оценки во время компиляции не определен; DMD в настоящее время делает это неопределенно в лексическом порядке, но это планируется изменить в ближайшем будущем. ‘static if’ и ‘mixin’ будут оцениваться в лексическом порядке, прежде чем будет сделано что-либо еще. После этого все остальное будет оцениваться по требованию.
Помимо прохода «static if / mixin», компиляция может выполняться параллельно (хотя текущая реализация этого еще не делает), что означает отсутствие упорядочения (несколько элементов могут завершать компиляцию одновременно).
Итак, надеюсь, это проясняет ситуацию.
Комментарии:
1. Я думаю, что проблема не совсем в
static if
per se — я думаю, что это может привести к сопоставлению шаблонов и псевдонимов, что довольно неожиданно изменит поведение кода, верно?2. Это не совсем то же самое с ними, но это связано и похоже. Порядок объявления шаблонов не влияет на ограничения шаблона, но порядок
static if
s может повлиять на них, и если они вводят новые символы, это может иметь эффект так же, какstatic if
. Я не верю, что порядокalias
es имеет какой-либо эффект, потому что они не связаны с условной компиляцией. Они просто вводят новый символ (который затем может повлиять на другиеstatic if
s, если они находятся внутри astatic if
, но их порядок сам по себе не влияет).