Existe um motivo para definir aliases de tipo em qualquer programa?

5

Eu comecei a aprender c ++ há algum tempo. É um assunto grande e eu não estou muito acostumado com isso ainda. Assim, esta pergunta é mais curiosa do que outra. No livro que li para aprender agora, há uma discussão sobre portabilidade. Eu concordo que a discussão é bem difícil para alguém no início do período de aprendizado, mas quando estou lendo, eu penso em algo.

O que eu imagino é: existe alguma razão para definir o tipo personalizado a ser usado em vez dos tipos internos básicos? Por exemplo, seria útil definir um tipo int_c como "int custom"? A razão que eu penso sobre isso é que algum código pode ser compilado, por exemplo, um compilador de 32 bits e um compilador de 64 bits. Parece que seria mais fácil, pois se você mudar de plataforma e todos os inteiros são definidos como int_c ao invés de int , já que este último exigiria a mudança de tipo em todo lugar em que um int é usado?

No entanto, também sei que <cstdint> contém definições de inteiro diferente como int64_t . No entanto, eu não ouvi falar de um cabeçalho com tipos de ponto flutuantes.

Então, para concluir: Existe uma razão para definir números inteiros ou flutuantes personalizados como int_c ou double_c ? Ou, em outro caso, qual é o melhor endereço?

    
por patrik 30.07.2014 / 19:19
fonte

1 resposta

7

Por vezes, existe uma razão para o fazer, no entanto <stdint.h> (em C99) ou <cstdint> (em C ++ 03 ou beter) tornam-nos menos óbvios.

Primeiro, há um problema de legibilidade. Se você definir

typedef unsigned myhash_t;

e mais tarde sempre usam myhash_t para números que são de fato hashes, você facilita o entendimento do seu código. Isso não ajuda muito em seus próprios erros (por exemplo, esquecer de declarar um parâmetro como myhash_t , mesmo que seja um hash), mas aumenta a legibilidade.

Depois, com <stdint.h> (etc ...), você tem muitos tipos integrais novos (a maioria deles são sinônimos específicos do sistema, por exemplo, int e long ), como int64_t (um int assinado de exatamente 64 bits), uintptr_t (um inteiro sem sinal com o mesmo tamanho de ponteiros), int_fast8t (um tipo integral, que é calculado rapidamente, de pelo menos 8 bits, mas pode ser 16 bits se eles rodarem mais rápido, etc ...)

Por fim, você pode colocar truques de pré-processador com, por exemplo, #if combinado a typedef -s. Por exemplo, você poderia definir uma codificação de cor como tendo 3 componentes RGB (ou 4, RGBA) de

 typedef uint8_t color_t;

mas algum truque de pré-processador pode fazer com que um uint16_t ....

FWIW, Ocaml e Ada estão se saindo melhor que o C ++ nesse aspecto. Eles são capazes de definir tipos integrais privados (ver, por exemplo, §7.9.2 em Ocaml ref .), Sobre o qual a aritmética é proibida (a menos que explicitamente permitido). Em C ++, você pode ter class MyHiddenInt { int x; /*etc*/ }; , mas pode ser representado e manipulado de forma diferente (ou seja, produzir código de máquina menos eficiente) do que alguns int . Os detalhes são, obviamente, ABI específicos. No Linux / x86-64 com a otimização -O2 , o código gerado GCC 4.9 (por exemplo, para uma adição) seria o mesmo.

Esses números inteiros particulares às vezes fazem sentido. Por exemplo, os descritores de arquivos Unix e Posix são int -s, mas fazer qualquer aritmética neles não faz sentido. (da mesma forma para myhash_t provavelmente, mas você não pode expressar essa restrição em C ++).

Para números flutuantes, é ainda mais importante. Em alguns processadores (por exemplo, alguns GPGPUs), a aritmética de precisão double é tão lenta que você deseja evitá-la. No nosso laptop & PCs dekstop, é o oposto: você quase sempre quer usar double (que hoje significa IEEE754 64 bits ponto flutuante), e use float (ou short ) apenas para espremer o consumo de memória. Essas opções são realmente específicas do processador (não são as mesmas em um tablet ou em um supercomputador).

Você poderia ir ainda mais longe e ter uma análise de tipo que leve em conta as dimensões físicas. Assim, você proíbe (em tempo de compilação) adicionar quilos com amperes ou watts, e que o produto de uma velocidade (em metro por segundo) com um tempo (em segundo) é um comprimento (em metro) que não deve ser aceitável como um arquivo descritor ou um hash.

Leia sobre os tipos de dados abstratos .

    
por 30.07.2014 / 19:26
fonte