Existe tipo de dados 'byte' em C ++?

86

Se existir, existe um arquivo de cabeçalho para incluir?

Este código dá erro de compilação:

#include <iostream>

using namespace std;

int main()
{
    byte b = 2;

    cout << b << endl;

    return 0;
}
user2972135
fonte
15
É chamado char.
Avidan Borisov
12
@Ben char é necessariamente um byte. Só que um byte não é necessariamente 8 bits.
Avidan Borisov
4
@Ben: Você aparentemente não está familiarizado com as plataformas mais exóticas que existem. Um byte certamente não é definido como 8 bits, independentemente do fato de que bytes de 8 bits sejam predominantes. É por isso que temos CHAR_BIT. Trabalhei em mais de um sistema embarcado em que os bytes não têm 8 bits de comprimento. Um char é definido para ter o tamanho 1, então sim, um char é sempre um byte.
Ed S.
11
@Ben: Os padrões C e C ++ definem inequivocamente um "byte" como o tamanho de a char, que é de pelo menos 8 bits. O termo "byte" pode ser definido de maneira diferente em outros contextos, mas ao discutir C ou C ++, é melhor seguir a definição do padrão.
Keith Thompson
3
OP, eu reconsideraria sua resposta aceita. Mesmo. Além disso, se é garantido que um char tem tamanho 1, por que anotar using byte = unsigned chare terminar com ele (como a resposta do rmp sugere)?
einpoklum

Respostas:

35

Não, não há tipo de dados de byte em C ++. No entanto, você sempre pode incluir o cabeçalho de bitset da biblioteca padrão e criar um typedef para byte:

typedef bitset<8> BYTE;

NB: Dado que WinDef.h define BYTE para código do Windows, você pode querer usar algo diferente de BYTE se sua intenção é direcionar o Windows.

Edit: Em resposta à sugestão de que a resposta está errada. A resposta não está errada. A pergunta era "Existe um tipo de dados 'byte' em C ++?". A resposta foi e é: "Não, não há tipo de dados de byte em C ++", conforme respondido.

Com relação à possível alternativa sugerida para a qual foi perguntado por que a alternativa sugerida é melhor?

De acordo com minha cópia do padrão C ++, na época:

"Objetos declarados como caracteres (char) devem ser grandes o suficiente para armazenar qualquer membro do conjunto de caracteres básicos da implementação": 3.9.1.1

Eu li isso para sugerir que, se uma implementação de compilador requer 16 bits para armazenar um membro do conjunto de caracteres básicos, o tamanho de um char seria de 16 bits. O fato de os compiladores de hoje tenderem a usar 8 bits para um char é uma coisa, mas pelo que eu posso dizer, certamente não há garantia de que serão 8 bits.

Por outro lado, "o bitset do modelo de classe <N> descreve um objeto que pode armazenar uma sequência consistindo de um número fixo de bits, N." : 20.5.1. Em outras palavras, ao especificar 8 como o parâmetro do modelo, acabo com um objeto que pode armazenar uma sequência de 8 bits.

Se a alternativa é melhor ou não para char, no contexto do programa que está sendo escrito, portanto, depende, tanto quanto eu entendo, embora possa estar errado, de seu compilador e seus requisitos no momento. Portanto, cabia ao indivíduo que redigia o código, no que me dizia respeito, determinar se a alternativa sugerida era apropriada para seus requisitos / desejos / necessidades.

Darren Gansberg
fonte
60
Como é bitset<8>melhor do que unsigned char?
Keith Thompson
13
Não é. use unsigned char
YasserAsmi
2
A resposta está errada e todas as outras estão erradas, exceto jwodder, que é a única resposta correta. byte é BIT_CHAR bits, não 8 bits.
Mark Galeck
14
Você pode querer atualizar esta resposta, pois agora há umstd::byte
NathanOliver
1
@Persixty ops por que eu disse BIT_CHAR. É um mistério. Um mistério do universo ..
Mark Galeck
88

Não, não há nenhum tipo chamado " byte" em C ++. O que você quer em vez disso é unsigned char(ou, se você precisar exatamente 8 bits, uint8_ta partir <cstdint>, desde C ++ 11 ). Observe que charnão é necessariamente uma alternativa precisa, como significa signed charem alguns compiladores e unsigned charem outros.

Jwodder
fonte
8
Não exatamente. char,, signed chare unsigned charsão três tipos distintos. chartem a mesma representação que um dos outros dois.
Keith Thompson
2
Se unsigned charfor maior que 8 bits, uint8_tnão será definido.
Keith Thompson
1
se você estiver em objetivo-c, pode ser necessário incluir em <stdint.h>vez de <cstdint>.
orion elenzil
2
@orionelenzil A pergunta era sobre C ++, não o objetivo C.
Pharap
2
@pharap - alguém escrevendo C ou C ++ em um contexto Objective-C pode achar meu comentário útil.
orion elenzil
42

Sim, existe std::byte(definido em <cstddef>).

C ++ 17 o introduziu.

maxschlepzig
fonte
2
std::bytenão pode ter aritmética executada nele, o que pode ser um obstáculo.
Pharap de
3
@Pharap, depende - não ser capaz de fazer cálculos aritméticos acidentalmente pode ser visto como uma vantagem para alguns casos de uso. Desde std::byteé apenas uma adição pode-se escolher a ferramenta certa para o trabalho (ou seja, quer std::byte, char, unsigned charou uint_8).
maxschlepzig
27

se estiver usando windows, em WinDef.h você tem:

typedef unsigned char BYTE;
rmp
fonte
22

Usando C++11lá está uma boa versão para um tipo de byte definido manualmente:

enum class byte : std::uint8_t {};

Isso é pelo menos o que o GSL faz.

Começando com C++17(quase) esta mesma versão é definida no padrão como std::byte(obrigado Neil Macintosh por ambos).

m8mble
fonte
4
Por que esse enum é melhor, em sua opinião, do que typedef unsigned char byte;ou typedef std::uint8_t byte;?
einpoklum
2
@einpoklum, aumenta a segurança de tipo. Por exemplo, você obtém um erro de compilação ao multiplicar acidentalmente esse valor de byte. Embora não ajude com o aliasing . Quando você deseja um alias apropriado para alguns bytes de que precisa char*, unsigned char*ou std::byte*.
maxschlepzig de
1
Exceto std::byteque não pode haver aritmética executada nele, o que pode ser um obstáculo.
Pharap de
4

Não, mas desde C ++ 11 existe [u] int8_t .

Sergei
fonte
1

Também há byte_lite , compatível com C ++ 98, C ++ 11 e posterior.

ruipacheco
fonte
1
namespace std
{
  // define std::byte
  enum class byte : unsigned char {};

};

Isso se sua versão C ++ não tiver std :: byte definirá um tipo de byte no namespace std. Normalmente você não quer adicionar coisas a std, mas neste caso é uma coisa padrão que está faltando.

std :: byte do STL faz muito mais operações.

Chris Reid
fonte