Walter Bright est le «dictateur bienveillant de toute une vie» du langage de programmation D et fondateur de Digital Mars . Il a des décennies d'expérience dans le développement de compilateurs et d'interprètes pour plusieurs langages, dont Zortech C ++, le premier compilateur C ++ natif. Il est également le créateur d' Empire , la principale source d'inspiration de Sid Meier's Civilization.
Le langage D a été conçu dès le départ pour accéder facilement et directement au C et, dans une moindre mesure, au C ++. Grâce à cela, d'innombrables bibliothèques C, la bibliothèque C standard et bien sûr les API système, qui sont généralement construites sur les API C, y sont disponibles.
Mais C ne concerne pas seulement les bibliothèques. De nombreux programmes volumineux et précieux sont écrits en C, comme le système d'exploitation Linux et la plupart des programmes associés. Alors que les programmes D peuvent accéder aux bibliothèques C, l'inverse n'est pas vrai. Les programmes C ne peuvent pas accéder au code D. Il est impossible (ou du moins très difficile) de compiler plusieurs fichiers D et de les lier dans un programme C. Le problème est que les fichiers D compilés peuvent accéder à quelque chose qui n'existe que dans le runtime D, et l'ajouter au lien est généralement peu pratique (le runtime est assez volumineux).
De plus, le code D ne peut pas exister dans un programme si D ne contrôle pas la fonction main()
, car c'est ainsi que démarre le runtime D. Par conséquent, les bibliothèques D sont inaccessibles aux programmes C et les programmes chimères (un mélange de C et D) deviennent peu pratiques. Vous ne pouvez pas simplement «essayer» D en ajoutant des modules D aux modules de programme C existants.
C'était jusqu'à ce que Better C.
Tout cela est déjà arrivé, l'idée n'est pas nouvelle. Bjarne Stroustrup en 1988 a écrit un article intitulé A Better C . Son premier compilateur C ++ pouvait compiler du code C presque inchangé, et il pouvait commencer à utiliser les fonctionnalités C ++ où et quand cela avait du sens - sans sacrifier le travail C ++ existant. C'était une stratégie brillante pour assurer le succès précoce de C ++.
— Kotlin, . Kotlin Java, Java-, Java Kotlin. Kotlin — « Java», .
D C
D C. C, , C ( , ..). D — D, , . -betterC
.
D D? , . . , C. , C D.
, , — , . , C: malloc
.
C++ COM , D — , .
, typeid
, , RAII . , , .
Better C RAII . (. .)
assert
, C D.
( , . Better C).
, Better C C?
C , . , : , , , , , , , (Compile Time Function Execution, CTFE), , (Design by Introspection, DbI).
:
#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 .
D:
import core.stdc.stdio;
extern (C) int main(int argc, char** argv) {
printf("hello world\n");
return 0;
}
: 23 068 . , C, D , . ( D 194 ). , D C .
Hello World — . - : :
#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;
}
Better C:
import core.stdc.stdio;
extern (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;
auto k = i + prime;
while (k < flags.length) {
flags[k] = false;
k += prime;
}
count += 1;
}
}
}
printf("%d primes\n", count);
return 0;
}
, - :
-
extern(C)
C. - D (thread-local storage, TLS). C .
__gshared
. -
foreach
— . -
const
,prime
. -
iter
,i
,prime
k
, . -
flags
flags.length
, - .
, : flags
. - ! .
Better C, , C. , D , , goto
.
En mon nom personnel, je peux dire que depuis que l'option est apparue -betterC
, j'ai commencé à traduire beaucoup de mes anciens programmes, mais encore utilisés, en D - une fonction à la fois. En travaillant une fonction à la fois et en exécutant une suite de tests après chaque modification, je fais fonctionner le programme à tout moment. Si quelque chose casse, je n'ai besoin que de tester une fonction pour trouver la cause. Je ne suis pas très intéressé à soutenir davantage mes programmes C, et avec l'avènement de Better C, il n'y a plus aucune raison à cela.