Является ли D «static if» декларативным или процедурным?

#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, если они находятся внутри a static if , но их порядок сам по себе не влияет).