Благодаря усилиями команды разработчиков языка у D теперь появилось совместимое с чистым Си подмножество обладающее не только привычным для любого программиста Си синтаксисом, но и значительно расширяющее функционал языка. Новое подмножество называется «betterC». Это подмножество позволяет перевести написание Си приложение на новый уровень.
Вот краткий список того, что позволяет режим betterC программисту:
1. Отсутствие препроцессора
2. Более высокая скорость компиляции
3. Полноценная модульность
3.1 Поддержка различных видов импорта (статический импорт, частичный импорт, ренейминг при импорте и тд)
4. В момент компиляции возможна: генерация кода, интроспекция, проверка различных условий
4.1 Ветвление на этапе компиляции через
static if и static foreach4.2 возможны работа блоков вида
version(linux) { ... }5. Шаблоны
6. Аналог borrow checking из Rust через
scope pointers (scope T*), scope slices (scope T[]) и scope references (scope ref T)7. Поддержка модификаторов доступа
const и immutable подробнее8. TLS по умолчанию
9. Поддержка контрактного программирования
10. Удобные массивы с поддержкой слайсинга
11. Ускорение работы с массивами за счет SIMD
12. Удобные unit-тесты
13. Встроенный профайлер
14. User-defined атрибуты
15. Встроенный и очень удобный генератор документации
16. Привычный каждому программисту Си синтаксис
17. Поддержка Unicode
18. Лучшая чем у C memory safety
19. Замыкания
20. Многое другое.
Давайте теперь рассмотрим примеры.
Следующий код на C:
#include <stdio.h> int main(int argc, char** argv) { printf("hello world\n"); return 0; }
Будет скомпилирован в:
_main: push EAX mov [ESP],offset FLAT:_DATA call near ptr _printf xor EAX,EAX pop ECX ret
Размер на выходе: 23,068 bytes.
Теперь тоже самое на D в режиме betterC:
import core.stdc.stdio; extern (C) int main(int argc, char** argv) { printf("hello world\n"); return 0; }
Размер на выходе: 23,068 bytes.
Не плохо правда ли? Тот же самый код без режиме betterC будет весить 194Kb.
Более сложный пример:
C версия:
#include <stdio.h> /* Eratosthenes Sieve prime number calculation. */ #define true 1 #define false 0 #define size 8190 #define sizepl 8191 char flags[sizepl]; int main() { int i, prime, k, count, iter; printf ("10 iterations\n"); for (iter = 1; iter <= 10; iter++) { count = 0; for (i = 0; i <= size; i++) flags[i] = true; for (i = 0; i <= size; i++) { if (flags[i]) { prime = i + i + 3; k = i + prime; while (k <= size) { flags[k] = false; k += prime; } count += 1; } } } printf ("\n%d primes", count); return 0; }
BetterC версия на D:
import core.stdc.stdio; extern (C): // указываем что надо использовать соглашение о вызове в стиле C __gshared bool[8191] flags; int main() { int count; printf("10 iterations\n"); foreach (iter; 1 .. 11) { count = 0; flags[] = true; foreach (i; 0 .. flags.length) { if (flags[i]) { const prime = i + i + 3; // const - значение никогда не будет меняться после инициализации auto k = i + prime; while (k < flags.length) { flags[k] = false; k += prime; } count += 1; } } } printf("%d primes\n", count); return 0; }
Получилось куда более читабельно и коротко.
Для инициализации пустого проекта вызовите:
dub initДля включения данного режима в dub.sdl необходимо добавить строку:
dflags "-betterC"Для dub.json строка будет:
"dflags" : ["betterC"],Требуется версия компилятора dmd 2.076 и старше.
Для начинающих программистов опубликована первая версия русского учебника по языку D.
Так же вышло новое расширение с поддержкой языка для Visual Code.