Manuel de suivi dynamique Solaris

Chapitre 2 Types, opérateurs et expressions

D permet d'accéder à de nombreux objets de données et de les manipuler : possibilité de créer et modifier des variables et des structures de données, d'accéder aux objets de données définis dans le noyau du système d'exploitation et aux processus utilisateur et de déclarer les nombres entiers, les virgules flottantes et les constantes de chaîne. D fournit un sur-ensemble des opérateurs ANSI-C utilisés pour manipuler des objets et créer des expressions complexes. Ce chapitre présente l'ensemble détaillé des règles concernant les types, les opérateurs et les expressions.

Noms d'identifiant et mots de passe

Les noms d'identifiant en D comprennent des majuscules et des minuscules, des chiffres et des traits de soulignement, le premier caractère devant être une lettre ou un trait de soulignement. Tous les noms d'identifiant commençant par un trait de soulignement (_) sont réservés aux bibliothèques système du langage D. Vous devez éviter d'utiliser de tels noms dans vos programmes en D. Les programmeurs en langage D attribuent, par convention, des noms combinant majuscules et minuscules aux variables et des noms ne comportant que des majuscules aux constantes.

Les mots-clés du langage D sont des identifiants spéciaux dont l'utilisation est réservée à la syntaxe du langage de programmation elle-même. Ces noms sont toujours spécifiés en minuscules et ne peuvent pas être attribués à des variables du langage D.

Tableau 2–1 Mots-clés de D

auto*

goto*

sizeof

break*

if*

static*

case*

import*+

string+

char

inline

stringof+

const

int

struct

continue*

long

switch*

counter*+

offsetof+

this+

default*

probe*+

translator+

do*

provider*+

typedef

double

register*

union

else*

restrict*

unsigned

enum

return*

void

extern

self+

volatile

float

short

while*

for*

signed

xlate+

D réserve un sur-ensemble de mots-clés en ANSI-C à utiliser comme mots-clés. Les mots-clés réservés pour un usage ultérieur par le langage D sont suivis du symbole “*”. Le compilateur D crée une erreur de syntaxe si vous essayez d'utiliser un mot-clé réservé à un usage ultérieur. Les mots-clés définis par D et non par ANSI-C sont suivis du symbole “+”. D fournit tous les types et opérateurs disponibles en ANSI-C. L'absence de structures de flux de commande constitue la principale différence dans la programmation D. Les mots-clés associés au flux de commande en ANSI-C sont réservés à un usage ultérieur dans D.

Types et tailles des données

D fournit des types de données fondamentaux pour les nombres entiers et les constantes à virgule flottante. Dans les programmes en D, l'arithmétique n'est réalisable que sur les nombres entiers. Vous pouvez utiliser les constantes à virgule flottante pour initialiser les structures de données, par contre, l'arithmétique à virgule flottante n'est pas autorisée dans D. D propose un modèle de données 32 et 64 bits pour les programmes d'écriture. Le modèle de données utilisé lors de l'exécution de votre programme correspond au modèle de données natif associé au noyau du système d'exploitation actif. Vous pouvez déterminer le modèle de données natif à l'aide de isainfo -b.

Le nom et la taille des types de nombre entier de chacun des deux modèles de données sont indiqués dans le tableau suivant. Les nombres entiers sont toujours représentés sous une forme à deux compléments dans l'ordre de codage natif des octets de votre système.

Tableau 2–2 Types de données des nombres entiers en D

Nom du type 

En 32–bits 

En 64–bits 

char

1 octet 

1 octet 

short

2 octets 

2 octets 

int

4 octets 

4 octets 

long

4 octets 

8 octets 

long long

8 octets 

8 octets 

Un préfixe ayant un qualificatif signed ou unsigned peut être ajouté aux types de nombre entier. En l'absence de qualificatif, le type est considéré comme étant signé. Le compilateur D fournit également les alias de type récapitulés dans le tableau suivant :

Tableau 2–3 Alias de type des nombres entiers en D

Nom du type 

Description 

int8_t

Nombre entier signé d'un octet 

int16_t

Nombre entier signé de 2 octets 

int32_t

Nombre entier signé de 4 octets 

int64_t

Nombre entier signé de 8 octets 

intptr_t

Nombre entier signé de la taille d'un pointeur 

uint8_t

Nombre entier non signé d'un octet 

uint16_t

Nombre entier non signé de 2 octets 

uint32_t

Nombre entier non signé de 4 octets 

uint64_t

Nombre entier non signé de 8 octets 

uintptr_t

Nombre entier non signé de la taille d'un pointeur 

Ces alias de type reviennent à utiliser le nom du type de base correspondant dans le tableau précédent. Par ailleurs, ils sont correctement définis pour chaque modèle de données. Par exemple, le nom de type uint8_t correspond à un alias du type unsigned char. Pour plus d'informations sur la procédure de définition de vos propres alias de types à utiliser dans vos programmes en D, reportez-vous au Chapitre8Définitions des types et des constantes.

D propose des types à virgule flottante pour garantir la compatibilité avec les types et les déclarations en ANSI-C. D ne prend pas en charge les opérateurs à virgule flottante mais la fonction printf() permet de suivre et de formater les objets de données à virgule flottante. Le tableau suivant présente les types à virgule flottante que vous pouvez utiliser :

Tableau 2–4 Types de données à virgule flottante en langage D

Nom du type 

En 32–bits 

En 64–bits 

float

4 octets 

4 octets 

double

8 octets 

8 octets 

long double

16 octets 

16 octets 

D fournit également le type spécial string pour représenter les chaînes ASCII. Vous trouverez de plus amples informations sur les chaînes dans le Chapitre6Chaînes de caractères.

Constantes

Vous pouvez écrire des constantes entières au format décimal (12345), octal (012345) ou hexadécimal (0x12345). Les constantes octales (base 8) doivent être précédées d'un zéro comme préfixe. Les constantes hexadécimales (base 16) doivent être précédées du préfixe 0x ou 0X. Est attribué aux constantes entières le plus petit type capable de représenter leur valeur entre int, long et long long. Si la valeur est négative, la version signée du type est utilisée. Si la valeur est positive et trop grande pour la représentation de type signé, la représentation de type non signé est utilisée. Vous pouvez appliquer l'un des suffixes suivants à toute constante entière pour spécifier son type D de manière explicite :

u ou U

Version unsigned du type sélectionné par le compilateur

l ou L

long

ul ou UL

unsigned long

ll ou LL

long long

ull ou ULL

unsigned long long

Les constantes à virgule flottante sont toujours rédigées avec une virgule décimale (12,345), un exposant ( 123e45) ou les deux (123,34e-5). Le type double est attribué par défaut aux constantes à virgule flottante. Vous pouvez appliquer l'un des suffixes suivants à toute constante à virgule flottante pour spécifier son type en langage D de manière explicite :

f ou F

float

l ou L

long double

Les constantes caractères sont écrites sous la forme d'un seul caractère ou d'une séquence d'échappement figurant entre guillemets simples ('a'). Le type int leur est attribué. Elles sont équivalentes à une constante entière dont la valeur est déterminée par la valeur du caractère dans le jeu de caractères ASCII. Pour obtenir la liste des caractères et de leurs valeurs, reportez-vous à ascii(5). Vous pouvez également utiliser l'une des séquences d'échappement spéciales présentées dans le tableau suivant dans vos constantes caractères. D prend en charge les mêmes séquences d'échappement détectées en ANSI-C.

Tableau 2–5 Séquences d'échappement de caractères en langage D

\a

alerte 

\\

barre oblique inversée 

\b

retour arrière 

\?

point d'interrogation 

\f

saut de page 

\'

guillemet simple 

\n

retour à la ligne 

\”

guillemet double 

\r

retour chariot 

\0oo

valeur octale 0oo

\t

onglet horizontal 

\xhh

valeur hexadécimale 0xhh

\v

onglet vertical 

\0

caractère null 

Vous pouvez ajouter plusieurs spécificateurs de caractère entre guillemets simples pour créer des nombres entiers dont chaque octet est initialisé en fonction des spécificateurs correspondants. Les octets sont lus de gauche à droite à partir de la constante caractère et affectés au nombre entier résultant dans l'ordre correspondant à l'endian-ness natif de votre système d'exploitation. Vous pouvez ajouter jusqu'à huit spécificateurs de caractère dans une seule constante caractère.

Vous pouvez créer des constantes chaînes à l'aide de guillemets doubles ("hello"). Une constante chaîne ne peut pas contenir de caractère littéral de retour à la ligne. Pour créer des chaînes contenant des retours à la ligne, utilisez la séquence d'échappement \n plutôt qu'un retour à la ligne littéral. Par contre, elles peuvent contenir n'importe laquelle des séquences d'échappement des caractères spéciaux récapitulés pour les constantes caractères ci-dessus. De même qu'en ANSI-C, les chaînes sont représentées sous la forme de tableaux de caractères terminés par un caractère null (\0) ajouté implicitement à chaque constante chaîne que vous déclarez. Le type D spécial string est affecté aux constantes chaînes. Le compilateur D fournit un ensemble de fonctions spéciales de comparaison et de suivi des tableaux de caractères déclarés en tant que chaînes, comme indiqué dans le Chapitre6Chaînes de caractères.

Opérateurs arithmétiques

Vous pouvez utiliser dans vos programmes les opérateurs arithmétiques fournis par D présentés dans le tableau suivant. Ces opérateurs ont la même signification pour les nombres entiers qu'en ANSI-C.

Tableau 2–6 Opérateurs arithmétiques binaires en langage D

+

addition de nombres entiers 

-

soustraction de nombres entiers 

*

multiplication de nombres entiers 

/

division de nombres entiers 

%

pourcentage de nombres entiers 

L'arithmétique en langage D ne peut être exécutée que sur des opérandes de nombre entier ou sur des pointeurs, comme indiqué dans le Chapitre5Pointeurs et ensembles. Les programmes en langage D ne permettent pas d'exécuter des opérations arithmétiques sur des opérandes à virgule flottante. L'environnement d'exécution de DTrace n'exécute aucune action sur le dépassement de capacité supérieur ou inférieur des nombres entiers. Vous devez vérifier vous-même ces conditions dans les situations dans lesquelles un dépassement de capacité inférieur ou supérieur peut se produire.

L'environnement d'exécution de DTrace ne contrôle ni ne signale automatiquement les erreurs de division par zéro induites par une utilisation incorrecte des opérateurs / et %. Si un programme D exécute une opération de division invalide, DTrace désactive automatiquement l'instrumentation affectée et signale l'erreur. Les erreurs détectées par DTrace n'ont aucune incidence sur les autres utilisateurs de DTrace ou sur le noyau du système d'exploitation. Par conséquent, nul besoin de vous inquiéter si votre programme en D contient par inadvertance l'une de ces erreurs.

En plus de ces opérateurs binaires, vous pouvez également utiliser les opérateurs + et - comme opérateurs unaires ; ces opérateurs ont une priorité plus élevée que tout autre opérateur arithmétique binaire. L'ordre de priorité et les propriétés d'associativité pour tous les opérateurs en D sont présentés dans le Tableau 2–11. Vous pouvez contrôler la priorité en regroupant les expressions entre parenthèses ( ).

Opérateurs relationnels

Vous pouvez utiliser dans vos programmes les opérateurs relationnels fournis par D présentés dans le tableau suivant. Ces opérateurs ont la même signification qu'en ANSI-C.

Tableau 2–7 Opérateurs relationnels en langage D

<

opérande gauche inférieur à l'opérande droit 

<=

opérande gauche inférieur ou égal à l'opérande droit 

>

opérande gauche supérieur à l'opérande droit 

>=

opérande gauche supérieur ou égal à l'opérande droit 

==

opérande gauche égal à l'opérande droit 

!=

opérande gauche différent de l'opérande droit 

Les opérateurs relationnels sont généralement utilisés pour écrire des prédicats en langage D. Chaque opérateur évalue la valeur du type int qui est égale à 1 si la condition est vraie et à 0 si la condition est fausse.

Vous pouvez appliquer les opérateurs relationnels aux paires de nombres entiers, aux pointeurs ou aux chaînes. Si des pointeurs sont comparés, le résultat revient à comparer les nombres entiers de deux pointeurs interprétés comme des nombres entiers non signés. Si des chaînes sont comparées, le résultat est déterminé en l'état en exécutant strcmp(3C) sur les deux opérandes. Voici un exemple de comparaisons de chaînes en langage D et des résultats correspondants :

"coffee" < "espresso"

... renvoie 1 (vrai) 

"coffee" == "coffee"

... renvoie 1 (vrai) 

"coffee" >= "mocha"

... renvoie 0 (faux) 

Vous pouvez également utiliser les opérateurs relationnels pour comparer des objets de données associés à un type d'énumération avec l'un des repères d'énumérateur définis par l'énumération. Les énumérations permettent de créer des constantes entières nommées et sont décrites plus en détails dans le Chapitre8Définitions des types et des constantes.

Opérateurs logiques

Vous pouvez utiliser dans vos programmes les opérateurs logiques binaires disponibles en langage D suivants. Les deux premiers opérateurs sont équivalents aux opérateurs ANSI-C correspondants.

Tableau 2–8 Opérateurs logiques de D

&&

AND logique : vrai si les deux opérandes sont vrais

||

OR logique : vrai si l'un des des deux opérandes est vrai

^^

XOR logique : vrai si exactement un opérande est vrai

Les opérateurs logiques sont généralement utilisés pour écrire des prédicats en langage D. L'opérateur AND logique exécute une évaluation en court-circuit : Si l'opérande gauche est faux, l'expression droite n'est pas évaluée. L'opérateur OR logique exécute une évaluation en court-circuit : Si l'opérande gauche est vrai, l'expression droite n'est pas évaluée. L'opérateur XOR logique ne fait pas de court-circuit : les deux opérandes d'expression sont toujours évalués.

Outre les opérateurs logiques binaires, vous pouvez également utiliser l'opérateur unaire ! pour exécuter une négation logique sur un seul opérande : ce dernier convertit un opérande 0 en un opérande 1 et un opérande non-zéro en opérande 0. Par convention, les programmeurs en langage D utilisent ! avec les nombres entiers destinés à représenter des valeurs booléennes et == 0 avec des nombres entiers non booléens même si ces deux expressions ont le même sens.

Vous pouvez appliquer les opérateurs logiques aux opérandes des types de nombre entier et de pointeur. Les opérateurs logiques interprètent les opérandes de pointeurs comme des valeurs entières non signées. De même qu'avec tous les opérateurs logiques et relationnels en langage D, les opérandes sont vrais s'ils possèdent une valeur entière non nulle et faux s'ils ont une valeur entière de zéro.

Opérateurs de bit

D propose les opérateurs binaires suivants pour manipuler les bits individuels dans les opérandes entiers. Ces opérateurs ont tous la même signification qu'en ANSI-C.

Tableau 2–9 Opérateurs de bit en langage D

&

Opérateur de bit AND 

|

Opérateur de bit OR 

^

Opérateur de bit XOR 

<<

Permet de décaler l'opérande gauche vers la gauche du nombre de bits spécifié par l'opérande droit 

>>

Permet de décaler l'opérande gauche vers la droite du nombre de bits spécifié par l'opérande droit 

L'opérateur binaire & permet d'effacer les bits à partir d'un opérande entier. L'opérateur binaire | permet de définir des bits dans un opérande entier. L'opérateur binaire ^ renvoie 1 à chaque position de bit à laquelle précisément un des bits d'opérande correspondant est défini.

Les décalages d'opérateurs permettent de déplacer des bits vers la gauche ou la droite dans un opérande entier donné. Le décalage à gauche remplit les emplacements de bit vides sur le côté droit du résultat avec des zéros. Le décalage à droite à l'aide d'un opérande entier non signé remplit les emplacements de bit vides à gauche du résultat avec des zéros. Le décalage à droite à l'aide d'un opérande entier signé remplit les emplacements de bit vides à gauche de la valeur du bit de signe. Cette opération s'appelle également un décalage arithmétique.

Le décalage d'une valeur entière par un nombre de bits négatif ou plus grand que le nombre de bits contenu dans l'opérande gauche lui-même crée un résultat non défini. Le compilateur D produit un message d'erreur s'il peut détecter cette condition lors de la compilation de votre programme en D.

Outre les opérateurs logiques binaires, vous pouvez également utiliser l'opérateur unaire ! pour exécuter une négation de bit sur un seul opérande : il convertit chaque bit 0 de l'opérande en bit 1 et chaque bit 1 de l'opérande en bit 0.

Opérateurs d'assignation

D fournit les opérateur d'assignation suivants pour modifier les variables en langage D. Vous ne pouvez modifier que les variables et les tableaux en langage D. Vous ne pouvez pas modifier les constantes et les objets de données du noyau à l'aide des opérateurs d'assignation en langage D. Les opérateurs d'assignation ont la même signification qu'en ANSI-C.

Tableau 2–10 Opérateurs d'assignation en langage D

=

permet d'indiquer que l'opérande gauche est égal à la valeur de l'expression droite 

+=

Permet d'incrémenter l'opérande gauche de la valeur de l'expression droite 

-=

Permet de décrémenter l'opérande gauche de la valeur de l'expression droite 

*=

Permet de multiplier l'opérande gauche par la valeur de l'expression droite 

/=

Permet de diviser l'opérande gauche par la valeur de l'expression droite 

%=

Permet d'effectuer le modulo de l'opérande gauche par la valeur de l'expression droite 

|=

Permet d'appliquer l'opérateur de bit OR à l'opérande de gauche avec la valeur de l'expression droite 

&=

Permet d'appliquer l'opérateur de bit AND à l'opérande de gauche avec la valeur de l'expression droite 

^=

Permet d'appliquer l'opérateur de bit XOR à l'opérande de gauche avec la valeur de l'expression droite 

<<=

Permet de décaler l'opérande gauche vers la gauche du nombre de bits spécifié par la valeur de l'expression droite 

>>=

Permet de décaler l'opérande gauche vers la droite du nombre de bits spécifié par la valeur de l'expression droite 

Les opérateurs d'assignation, hormis =, sont fournis comme abrégés, afin d'utiliser l'opérateur = avec l'un des autres opérateurs décrits précédemment. Par exemple, l'expression x = x + 1 équivaut à l'expression x += 1 si ce n'est que l'expression x est déterminée une seule fois. Ces opérateurs d'assignation obéissent aux mêmes règles pour les types d'opérande que les formes binaires décrites précédemment.

Le résultat d'un opérateur d'assignation correspond à une expression équivalant à la nouvelle valeur de l'expression gauche. Vous pouvez associer les opérateurs d'assignation ou tout autre opérateur décrit dans ce document pour former des expressions d'une complexité arbitraire. Vous pouvez utiliser des parenthèses ( ) pour regrouper des termes dans des expressions complexes.

Opérateurs d'incrément et de décrément

D propose les opérateurs unaires spéciaux ++ et -- pour incrémenter et décrémenter les pointeurs et les nombres entiers. Ces opérateurs ont la même signification qu'en ANSI-C. Vous ne pouvez les appliquer qu'aux variables, avant ou après le nom de la variable. Si l'opérateur apparaît avant le nom de la variable, la variable est modifiée en premier, puis l'expression qui en résulte équivaut à la nouvelle valeur de la variable. Par exemple, les deux expressions suivantes produisent des résultats identiques :

x += 1;

y = ++x;

y = x;

 

Si l'opérateur apparaît après le nom de la variable, cette dernière est modifiée après renvoi de sa valeur actuelle, afin de l'utiliser dans l'expression. Par exemple, les deux expressions suivantes produisent des résultats identiques :

y = x;

y = x--;

x -= 1;

 

Vous pouvez utiliser les opérateurs d'incrément et de décrément pour créer de nouvelles variables sans les déclarer. Si la déclaration d'une variable est omise alors que l'opérateur d'incrément ou de décrément est appliqué à une variable, la variable est implicitement déclarée de type int64_t.

Vous pouvez appliquer les opérateurs d'incrément et de décrément aux variables de nombres entiers, auquel cas les opérateurs incrémentent ou décrémentent la valeur correspondant de 1, ou aux variables de pointeurs, auquel cas les opérateurs incrémentent ou décrémentent l'adresse du pointeur de la taille du type de données référencé par le pointeur. Les pointeurs et l'arithmétique de pointeur en D sont présentés dans le Chapitre5Pointeurs et ensembles.

Expressions conditionnelles

Bien que le langage D ne prenne pas en charge de constructions if-then-else, il supporte les expressions conditionnelles simples employant les opérateurs ? et :. Ces opérateurs permettent d'associer un triplet d'expressions, la première expression étant utilisée pour déterminer de manière conditionnelle l'une des deux autres. Vous pourriez, par exemple, utiliser l'énoncé en langage D suivant pour définir une variable x sur l'une des deux chaînes en fonction de la valeur de i :

x = i == 0 ? "zero" : "non-zero";

Dans cet exemple, l'expression i == 0 est évaluée en premier pour déterminer si elle est vraie ou fausse. Si la première expression est vraie, la seconde est évaluée et l'expression ?: renvoie sa valeur. Si la première expression est fausse, la troisième est évaluée et l'expression ?: renvoie sa valeur.

Comme pour tout opérateur en D, vous pouvez utiliser plusieurs opérateurs ?: dans une seule expression, de manière à créer plus d'expressions complexes. Par exemple, l'expression suivante devra prendre une variable char c contenant l'un des caractères 0-9, a-z ou A-Z et renvoyer la valeur de ce caractère une fois interprété comme un chiffre dans un nombre entier hexadécimal (base 16) :

hexval = (c >= '0' && c <= '9') ? c - '0' :
    (c >= 'a' && c <= 'z') ? c + 10 - 'a' : c + 10 - 'A';

La première expression utilisée avec ?: doit être un pointeur ou un nombre entier pour pouvoir déterminer si sa valeur est vraie. La seconde et la troisième expression peuvent appartenir à n'importe quel type compatible. Vous ne pouvez pas construire d'expression conditionnelle lorsque, par exemple, un chemin d'accès renvoie une chaîne alors qu'un autre chemin d'accès renvoie un nombre entier. La seconde et la troisième expression ne peuvent pas non plus invoquer de fonction de suivi comme trace() ou printf(). Si vous souhaitez assurer le suivi conditionnel des données, utilisez plutôt un prédicat, comme indiqué dans le Chapitre1Introduction.

Conversions de types

Lorsque des expressions sont construites à l'aide d'opérandes de types différents mais compatibles, les types sont convertis de manière à déterminer celui de l'expression résultante. Les règles en langage D concernant les conversions de types sont identiques aux règles de conversion arithmétique des nombres entiers en ANSI-C. Ces règles sont parfois appelées conversions arithmétiques usuelles.

Il est possible de décrire tout simplement les règles de conversion comme suit : Chaque type d'entier est classé dans l'ordre char, short, int, long, long long, sachant que les types correspondants non signés apparaissent au-dessus de leur équivalent signé mais en dessous du type d'entier suivant. Lorsque vous construisez une expression à l'aide de deux opérandes entiers comme x + y et que ces opérandes appartiennent à un type d'entier différent, le type d'opérande le plus haut classé sert de type de résultat.

Si une conversion s'impose, l'opérande de niveau inférieur est le premier promu au type de niveau supérieur. La promotion ne modifie pas vraiment la valeur de l'opérande : elle étend seulement la valeur vers un conteneur plus grand en fonction de son signe. Si un opérande non signé est promu, les bits supérieurs non utilisés du nombre entier résultant sont remplis avec des 0. Si un opérande signé est promu, les bits supérieurs non utilisés sont remplis par l'extension du signe d'exécution. Si un type signé est converti en type non signé, le signe du type signé est d'abord étendu, puis le nouveau type non signé, déterminé par la conversion, lui est affecté.

Les nombres entiers et les autres types peuvent également être convertis explicitement d'un type en un autre. En langage D, vous pouvez convertir les pointeurs et les nombres entiers en n'importe quel type de pointeur ou de nombre entier mais pas en un autre type. Les règles de conversion et de promotion des chaînes et des tableaux de caractères sont traitées dans le Chapitre6Chaînes de caractères. La conversion d'un entier ou d'un pointeur est créée à l'aide d'une expression telle que :

y = (int)x;

le type de destination étant placé entre parenthèses et servant de préfixe à l'expression de la source. Les nombres entiers sont convertis en des types de niveau supérieur par l'intermédiaire d'une promotion. Ils sont convertis en types de niveau inférieur en transformant en zéro les bits supérieurs superflus du nombre entier.

Comme D n'autorise pas l'arithmétique en virgule flottante, aucune conversion d'opérande en virgule flottante n'est autorisée et aucune règle de conversion en virgule flottante implicite n'est définie.

Priorité

Les règles en langage D concernant la priorité et l'associativité des opérateurs sont décrites dans le tableau suivant. Ces règles sont quelque peu complexes mais nécessaires pour assurer une compatibilité précise avec les règles de priorité des opérateurs ANSI-C. Les entrées du tableau sont triées par ordre de priorité, de la plus élevée à la plus faible.

Tableau 2–11 Priorité et associativité des opérateurs de D

Opérateurs 

Associativité 

() [] -> .

gauche à droite 

! ~ ++ -- + - * & (type) sizeof stringof offsetof xlate

droite à gauche 

* / %

gauche à droite 

+ -

gauche à droite 

<< >>

gauche à droite 

< <= > >=

gauche à droite 

== !=

gauche à droite 

&

gauche à droite 

^

gauche à droite 

|

gauche à droite 

&&

gauche à droite 

^^

gauche à droite 

||

gauche à droite 

?:

droite à gauche 

= += -= *= /= %= &= ^= |= <<= >>=

droite à gauche 

,

gauche à droite 

Le tableau comprend plusieurs opérateurs qui n'ont pas encore été présentés ; ils seront traités dans des chapitres ultérieurs :

sizeof

Calcule la taille d'un objet (Chapitre7Structs et Unions)

offsetof

Calcule le décalage d'un membre type (Chapitre7Structs et Unions)

stringof

Convertit l'opérande en chaîne (Chapitre6Chaînes de caractères)

xlate

Convertit un type de données (Chapitre40Translateurs)

& unaire

Calcule l'adresse d'un objet (Chapitre5Pointeurs et ensembles)

* unaire

Déréférence un pointeur sur un objet (Chapitre5Pointeurs et ensembles)

-> et .

Accède à un membre d'une structure ou d'un type d'union (Chapitre7Structs et Unions)

L'opérateur , (virgule) présenté dans le tableau est dédié à la compatibilité avec l'opérateur ANSI-C correspondant et permet notamment d'évaluer un ensemble d'expressions de gauche à droite et de retourner la valeur de l'expression de poids faible. Cet opérateur n'est fourni que pour la compatibilité avec le langage C et ne doit généralement pas être utilisé.

L'entrée () du tableau sur la priorité des opérateurs représente un appel de fonction. Des exemples d'appel de fonction, comme printf() et trace(), sont présentés dans le Chapitre1Introduction. La virgule sert également en langage D à énumérer des arguments en fonctions et à constituer des listes de clés de tableaux associatifs. Cette virgule n'a rien à voir avec l'opérateur et n'assure aucune évaluation de gauche à droite. Le compilateur D ne garantit en rien l'ordre d'évaluation des arguments en fonction ou des clés en tableau associatif. Vous devez veiller à utiliser des expressions aux effets obliques interagissants, comme la paire d'expressions i et i++, dans ces contextes.

L'entrée [] du tableau de priorité des opérateurs représente un tableau ou une référence de tableau associatif. Des exemples de tableaux associatifs sont présentés dans le Chapitre1Introduction. Un type spécial de tableau associatif, appelé groupement, est décrit dans le Chapitre9Groupements. Vous pouvez également utiliser l'opérateur [] pour créer des index dans des tableaux C au format fixe, comme indiqué dans le Chapitre5Pointeurs et ensembles.