Guia de rastreamento dinâmico Solaris

Espaços de nome de tipo

Esta seção discute os espaços de nome de D e as questões de espaço de nome relacionadas a tipos. Em linguagens tradicionais como ANSI-C, a visibilidade do tipo é determinada pelo fato de um tipo estar ou não aninhado em uma função ou outra declaração. Os tipos declarados no escopo externo de um programa em C são associados a um espaço de nome global único e são visíveis em todo o programa. Os tipos definidos nos arquivos de cabeçalho de C são geralmente incluídos nesse escopo externo. Ao contrário dessas linguagens, D fornece acesso a tipos de vários escopos externos.

A linguagem D facilita a observação dinâmica em várias camadas de uma pilha de software, incluindo o kernel do sistema operacional, um conjunto associado de módulos carregáveis do kernel e processos do usuário em execução no sistema. Um único programa em D pode instanciar testes para coletar dados de vários módulos do kernel ou outras entidades de software compiladas em objetos binários independentes. Portanto, pode haver mais de um tipo de dados do mesmo nome, talvez com definições diferentes, no universo de tipos disponíveis para o DTrace e o compilador de D. Para gerenciar essa situação, o compilador de D associa cada tipo a um espaço de nome identificado pelo objeto do programa que o contém. Tipos de um objeto de programa em particular podem ser acessados especificando-se o nome do objeto e o operador de escopo de aspa invertida (`) em qualquer nome de tipo.

Por exemplo, se um módulo do kernel denominado foo contiver a seguinte declaração do tipo C:

typedef struct bar {
	int x;
} bar_t;

então os tipos struct bar e bar_t poderiam ser acessados de D usando-se os nomes de tipo:

struct foo`bar				foo`bar_t

O operador de aspa invertida pode ser usado em qualquer contexto em que um nome de tipo seja apropriado, incluindo a especificação do tipo de declarações de variável de D ou expressões de difusão em cláusulas de teste de D.

O compilador de D também fornece dois espaços de nome de tipo incorporados especiais que usam os nomes C e D respectivamente. O espaço de nome de tipo de C é inicialmente preenchido com os tipos intrínsecos padrão de ANSI-C como int. Além disso, as definições de tipo obtidas usando-se o pré-processador de C cpp(1) e a opção dtrace -C serão processadas pelo escopo de C e adicionadas nele. Como resultado, você pode incluir arquivos de cabeçalho de C, contendo declarações de tipo que já estão visíveis, em outro espaço de nome de tipo sem causar um erro de compilação.

O espaço de nome do tipo de D é preenchido inicialmente com elementos intrínsecos do tipo de D como int e string, assim como os alias de tipo de D incorporados como uint32_t. Todas as novas declarações de tipo que aparecerem na origem do programa em D serão automaticamente adicionadas ao espaço de nome de tipo D. Se você criar um tipo complexo como uma struct no seu programa em D, consistindo em tipos de membro de outros espaços de nome, os tipos de membro serão copiados para o espaço de nome de D pela declaração.

Quando o compilador de D encontra uma declaração de tipo que não especifica um espaço de nome explícito usando o operador de aspa invertida, o compilador pesquisa o conjunto de espaços de nome de tipo ativo para localizar uma correspondência usando o nome de tipo especificado. O espaço de nome de C sempre é pesquisado primeiro, seguido pelo espaço de nome de D. Se o nome do tipo não for encontrado no espaço de nome de C ou D, os espaços de nome de tipo dos módulos ativos do kernel serão pesquisados em ordem crescente por ID do módulo do kernel. Essa ordenação garante que os objetos binários que formam o kernel do núcleo sejam pesquisados antes de quaisquer módulos carregáveis do kernel, mas não garante quaisquer propriedades de ordenação entre os módulos carregáveis. Você deve usar o operador de escopo ao acessar tipos definidos em módulos carregáveis do kernel para evitar conflitos de nome de tipo com outros módulos do kernel.

O compilador de D usa informações de depuração compactadas de ANSI-C fornecidas com os módulos do kernel do núcleo do Solaris para acessar automaticamente os tipos associados ao código-fonte do sistema operacional sem a necessidade de acessar os arquivos de inclusão correspondentes de C. Essas informações de depuração simbólicas podem não estar disponíveis para todos os módulos do kernel no seu sistema. O compilador de D irá reportar um erro se você tentar acessar um tipo dentro do espaço de nome de um módulo que não possua as informações de depuração compactadas de C destinadas para uso com o DTrace.