Manuel de suivi dynamique Solaris

Espaces de noms de types

Cette section présente les espaces de noms en D et les problèmes d'espace de noms liés aux types. Dans les langages classiques comme l'ANSI-C, la visibilité du type est déterminée par le type d'imbrication (à l'intérieur d'une fonction ou d'une autre déclaration). Les types déclarés dans l'étendue extérieure d'un programme en C sont associés à un espace de noms global unique et sont visibles à travers tout le système. Les types définis dans les fichiers d'en-tête en C figurent généralement dans cette étendue extérieure. Contrairement à ces langages, le langage D permet d'accéder aux types à partir de plusieurs étendues extérieures.

Le langage D facilite l'observation dynamique à travers plusieurs couches d'une pile logicielle, y compris le noyau du système d'exploitation, un ensemble associé de modules de noyau chargeables et les processus utilisateur en cours d'exécution sur le système. Un seul programme en D peut instancier des sondes pour rassembler des données issues de plusieurs modules de noyau ou d'autres entités logicielles qui sont compilées dans des objets binaires indépendants. Par conséquent, plusieurs types de données possédant le même nom mais pas nécessairement la même définition, peuvent figurer parmi les types disponibles pour DTrace et le compilateur D. Pour gérer cette situation, le compilateur D associe chaque type à un espace de noms identifié par l'objet de programme qu'il contient. Les types d'un objet de programme particulier sont accessibles en spécifiant le nom de l'objet et en utilisant l'opérateur d'étendue ` dans n'importe quel nom de type.

Par exemple, si un module de noyau nommé foo contient la déclaration de type en langage C suivante :

typedef struct bar {
	int x;
} bar_t;

les types struct bar et bar_t sont accessibles à partir du langage D à l'aide des noms de type :

struct foo`bar				foo`bar_t

Vous pouvez utiliser l'opérateur ` dans n'importe quel contexte dès lors qu'un nom de type est approprié, y compris lors de la spécification du type pour les déclarations de variable en D ou les expressions de diffusion dans des clauses de sonde en D.

Le compilateur D intègre également deux espaces de noms de types spéciaux qui portent respectivement les noms C et D. L'espace de noms de types C comprend à l'origine les types ANSI-C standard intrinsèques comme int. Par ailleurs, les définitions de type acquises à l'aide du préprocesseur C cpp(1) au moyen de l'option dtrace -C sont traitées par et ajoutées à l'étendue de C. Vous pouvez ainsi inclure des fichiers d'en-tête en C contenant des déclarations de types déjà visibles dans un autre espace de noms de types sans engendrer d'erreur de compilation.

L'espace de noms de types D comprend à l'origine les types D intrinsèques comme int et string, ainsi que des alias de types D intégrés comme uint32_t. Toute nouvelle déclaration de types qui apparaît dans la source du programme en D est automatiquement ajoutée à l'espace de noms de types D. Si vous créez dans votre programme en D un type complexe, comme une struct, constitué de types de membre provenant d'autres espaces de noms, les types de membre sont copiés dans l'espace de noms D par la déclaration.

Lorsque le compilateur D rencontre une déclaration de type ne spécifiant aucun espace de noms de manière explicite à l'aide de l'opérateur `, le compilateur recherche l'ensemble des espaces de noms de types actifs pour trouver une correspondance à l'aide du nom de type spécifié. L'espace de noms C est toujours recherché en premier, suivi de l'espace de noms D. Si le nom du type n'est trouvé ni dans l'espace de noms C ni dans l'espace de noms D, la recherche des espaces de noms de types des modules de noyau actifs est réalisée dans l'ordre ascendant par ID de module de noyau. Cet ordre garantit que la recherche des objets binaires qui constitue le noyau de base est exécutée avant la recherche des modules de noyau chargeables. Par contre, il ne garantit pas l'ordre des propriétés au niveau des modules chargeables. Vous devez utiliser l'opérateur d'étendue lorsque vous accédez aux types définis dans les modules de noyau chargeables pour éviter les conflits de nom de type avec les autres modules de noyau.

Le compilateur D utilise les informations de débogage en ANSI-C compressées fournies avec les modules de noyau de base de Solaris afin d'accéder automatiquement au code source du système d'exploitation sans devoir accéder aux fichiers en C inclus correspondants. Ces informations de débogage symboliques peuvent ne pas être disponibles pour tous les modules de noyau sur votre système. Le compilateur D signale une erreur si vous tentez d'accéder à un type dans un espace de noms d'un module qui empile les informations de débogage en C compressées dont l'utilisation est prévue avec DTrace.