Por que fluxos de C ++ usar carvão em vez de unsigned char?
Pergunta
Eu sempre me perguntei por que a biblioteca C ++ padrão foi instanciado basic_ fluxo [io] e todas as suas variantes que utilizam o tipo char
em vez do tipo unsigned char
. meios char
(dependendo se ele está assinado ou não) você pode ter estouro positivo e negativo para operações como get (), o que levará ao valor definido pela implementação das variáveis ??envolvidas. Outro exemplo é quando você quer a saída de um byte, não formatado, a um ostream usando sua função put
.
Todas as idéias?
Nota ??strong>: Eu ainda não estou realmente convencido. Então, se você sabe a resposta definitiva, você ainda pode publicá-la de fato.
Solução
Possivelmente eu tenha entendido mal a pergunta, mas a conversão de char não assinado para caractere não é especificado, é dependente de implementação (4,7-3 no C ++ padrão).
O tipo de um carácter de 1 byte no C ++ é "carvão", não "unsigned char". Isto dá implementações um pouco mais liberdade para fazer a melhor coisa sobre a plataforma (por exemplo, o corpo de padrões pode ter acreditado que existem CPUs onde assinou aritmética byte é mais rápido do que aritmética byte não assinado, embora isso seja especulação da minha parte). Também para compatibilidade com C. O resultado da remoção deste tipo de incerteza existencial do C ++ é C #; -)
Uma vez que o tipo de "char" existe, eu acho que faz sentido para os fluxos habituais de usá-lo, embora o seu signedness não está definido. Então, talvez a sua pergunta é respondida pela resposta, "por que não C ++ apenas definir char para ser assinado?"
Outras dicas
Sempre entendi que desta forma: a finalidade da classe iostream
é ler e / ou escrever um fluxo de caracteres, que, se você pensar sobre isso, são entidades abstratas que só são representados pelo computador usando um personagem codificação. O C ++ marcas padrão um grande esforço para evitar fixando-se a codificação de caracteres, dizendo apenas que "objetos declarados como personagens (char
) deve ser grande o suficiente para armazenar qualquer membro do conjunto de caracteres básicos da implementação", porque ele não precisa forçar o "a implementação do conjunto de caracteres básico" para definir a linguagem C ++; o padrão pode deixar a decisão de que codificação de caracteres é usado para a implementação (compilador juntamente com uma implementação STL), e apenas observar que objetos char
representar caracteres individuais em alguns codificação.
Um escritor implementação podia escolher um único octeto que codifica tais como ISO-8859-1 ou mesmo uma dupla octeto que codifica tais como UCS-2 . Não importa. Enquanto um objeto char
é "grande o suficiente para armazenar qualquer membro do conjunto de caracteres básicos da implementação" (note que este explicitamente proíbe codificações de comprimento variável ), em seguida, a implementação pode até escolher uma codificação que representa latino básico de uma forma que é incompatível com qualquer codificação comum!
É confuso que o char
, tipos signed char
e unsigned char
share "char" em seus nomes, mas é importante ter em mente que char
não pertence à mesma família de tipos fundamentais como signed char
e unsigned char
. signed char
é na família de tipos inteiros assinados:
Há quatro inteiro assinado tipos : "long int" "char assinado", "short int", "int", e
e unsigned char
é na família de tipos inteiros não assinados:
Para cada um dos inteiro assinado tipos, existe um correspondente (mas diferente) tipo inteiro não assinado : "char não assinado", "short int não assinado", "int não assinado", e "unsigned long int," ...
A uma similaridade entre os tipos char
, signed char
, e unsigned char
é que "[eles] ocupam a mesma quantidade de armazenamento e têm os mesmos requisitos de alinhamento". Assim, você pode reinterpret_cast
de char *
para unsigned char *
a fim de determinar o valor numérico de um caractere no conjunto de caracteres execução.
Para responder à sua pergunta, a razão pela qual os usos STL char
como o tipo padrão é porque os fluxos padrão são destinadas para ler e / ou escrever fluxos de personagens, representados por objetos char
, não inteiros (signed char
e unsigned char
). O uso de char
versus o valor numérico é uma maneira de separar preocupações.
char é para caracteres, sem assinatura char para bytes de dados e caracteres para assinados, bem dados, assinados.
Norma não especifica se assinado ou unsigned char será utilizado para a implementação de carvão - que é específico do compilador. Ele só especifica que o "char" será "suficiente" para personagens de espera em seu sistema -. A forma como os personagens estavam naqueles dias, o que é, não Unicode
Usando o "char" para caracteres é a maneira padrão para ir. Usando unsigned char é um hack, embora ele vai coincidir com a implementação do compilador de carvão na maioria das plataformas.
este comentário explica-lo bem. Para citar:
caractere assinado e sem assinatura char são aritméticas, tipos integrais assim como int e int não assinado. Por outro lado, char é expressamente destinado a ser do tipo "I / O" que representa alguns opaco, unidade fundamental específico do sistema de dados sobre sua plataforma. Eu iria usá-los neste espírito.