Чи D "статичний, якщо" декларативний чи процедурний?

Розглянемо наступний код:

static if (!is(MyStruct))
{
    struct MyStruct
    {
    }
}

static if (is(MyStruct))
{
    static assert(0);
}

Моє оригінальне розуміння полягало в тому, що порядок декларувань (у глобальному масштабі) не має значення в D.

Однак у цьому випадку порядок static if s робить різницю між тим, чи програма збирається чи ні.

Отже, чи є процедура оцінки D для компіляції, процедурна функція (наприклад, C/C ++), декларативна функція чи щось інше? Що це зараз, і що планується (якщо вони різні)?


Редагувати:

Я просто зрозумів, що проблема навіть не закінчиться тут. Що відбувається з static, якщо використовує .tupleof , щоб перерахувати членів поточного модуля, і створити той же тип проблеми?

5

2 Відповіді

Це ускладнюється. Це по суті декларативний, але порядок може мати значення, коли static, якщо вводить новий символ. Крім того, я не вважаю, що воно коли-небудь важливо, але, як показує ваш приклад, коли ви вводите новий символ в static if , а інший статичний, якщо використовує це, безумовно, може мати значення.

Нещодавно було зроблено деяку дискусію про те, як це зробити як послідовний та інтуїтивний наскільки це можливо. Тому, особливо в кутових ситуаціях, ситуація може змінитися найближчим часом. Але я б очікував, що ваш приклад буде продовжувати запускати static assert . Питання в тому, чи буде він запускати static assert , якщо ви скасуєте порядок блоків static if , і я не впевнений, що це дійсно вирішено ще. обговорення в ньому в групі новин компілятора не є цілком вирішальний і трохи важко слідувати ІМХО, тому я не можу точно сказати. Але я сподіваюсь, що замовлення все одно матиме значення, принаймні в деяких випадках, коли із блокуванням static if буде введено новий символ.

РЕДАГУВАТИ:

Це було нещодавно опубліковане одного з основних вкладників dmd:

В даний час порядок оцінки часу компіляції не визначено; DMD   В даний час це неясно в лексичному порядку, але це планується   зміниться в найближчому майбутньому. 'static if' і 'mixin' будуть оцінені   в лексичному порядку, перш ніж все ще буде зроблено. Після цього   все інше буде оцінюватися за вимогою.

     

Окрім проходу "static if/mixin", можна продовжити компіляцію   паралельно (хоча поточна реалізація ще цього не робить), яка   означає, що немає замовлення (кілька елементів можуть завершити компіляцію   одночасно).

Отже, сподіваюся, що висвітлює речі.

2
додано
Я думаю, що проблема не зовсім з проблемою static if per se - я думаю, що він може придумати відповідність шаблону та псевдоніми, змінивши поведінку коду досить несподівано, вірно?
додано Автор Mehrdad, джерело
З ними не точно, але це пов'язано і схоже. Порядок декларування шаблонів не впливає на обмеження шаблону, але порядок static if s може вплинути на них, і якщо вони вводять нові символи, які можуть мати ефект так само, як статичний, якщо . Я не вірю в те, що порядок псевдоніму має якісь ефекти, тому що вони не включають умовну компіляцію. Вони просто вводять новий символ (який може вплинути на інші static if s, якщо вони знаходяться всередині static, якщо , але їх замовлення не впливає на них самих). .
додано Автор Jonathan M Davis, джерело

Це декларативна функція, яка має процедурні властивості як побічний ефект реалізації.

2
додано
Я думаю, що дещо поговорили про те, щоб цей приклад коду було незаконним. Або відкидаючи це прямо або оголосивши це невизначеною поведінкою.
додано Автор BCS, джерело
@Mehrdad Не обов'язково, особливо в загальних випадках. Одним з підходів буде те, що is() "ловушка" для стільниці символу, а потім вважатиме помилкою вставити символ, який змінить значення вже оціненого static, якщо
додано Автор BCS, джерело
@Mehrdad: Будучи невідповідним у різних модулях, кодекс OP показує точку: скажіть, що другий if запускається першим, він нічого не робить, а тоді запускається перший if " пастки "символ MyStruct , а потім спробує додати, що просте відключення лову, і дає повідомлення про помилку. Якщо все відбувається іншим способом, одне повідомлення про помилку дається, навіть не переходячи до другого if . - OTOH це працює, зробивши найбільш корисну версію проблеми незаконною.
додано Автор BCS, джерело
@Mehrdad: перехресна модульна інтерференція вже існує, тому що намагання використовувати символ (не повністю кваліфікований), який визначається з декількох модулів, викликає помилку. Я думаю, рішення для цього випадку є статичний імпорт або щось подібне.
додано Автор BCS, джерело
@Mehrdad Мовчазна ловушка буде встановлена ​​на кожному пошуковому знаку символу під час оцінки умовного значення на static, якщо незалежно від того, наскільки далеко від нього є if .
додано Автор BCS, джерело
@BCS: чи це неможливо виявити? Принаймні, коли міксіни вступають у гру, це виглядає як проблема зупинки ....
додано Автор Mehrdad, джерело
@BCS: Як це правильно працює, якщо два модулі мали перехресну взаємодію, і вони обидва перевіряли типи один одного? Який з них перший? Якщо це важливо? Чи слід мати можливість блокувати компіляцію іншого?
додано Автор Mehrdad, джерело
@ Меддрад: Лол, я сама О.П. : P Так, ми говоримо одне і теж - наявність у тому самому модулі не має відношення до проблеми; це моя точка. Проблема відбувається в будь-якому випадку. Але зараз проблема полягає в тому, що для цілого модуля можна запобігти збірці з іншого модуля просто з-за зіткнення - що, здавалося, трохи дивовижно для мене ідеї. Може, це просто я, хоч, ідк ...
додано Автор Mehrdad, джерело
@BCS: я просто зрозумів іншу причину, чому ви не можете зробити це "ловушкою" так легко: ви можете обійти is (MyStruct) з is (typeof ({MyStruct a;}) ) або будь-які довільно складні. Чи може/чи повинен компілятор це все розібратись?
додано Автор Mehrdad, джерело