Vejo variáveis definidas com esse tipo, mas não sei de onde elas vêm, nem qual é seu objetivo. Por que não usar int ou unsigned int? (E quanto a outros tipos "semelhantes"? Void_t, etc).
@kjfletch: hhhmmm, é estranho que procurar pelo termo 'size_t' (como eu fiz anteriormente) não retorne essa pergunta.
Eliseo Ocampos
1
@Eliseo - A função de busca do Stackoverflow é péssima. Use o Google com um parâmetro 'site: stackoverflow.com'.
22711 Michael Burr
8
O OP perguntou especificamente Onde encontro a definição de size_t? Eu cheguei aqui procurando a mesma coisa. O dup citado não discute onde encontrar a declaração.
jww 27/07
9
Obviamente, essa pergunta não é a mesma que a vinculada. "Onde encontro alguma coisa" não é a mesma coisa que "Qual é a diferença entre" (mesmo que a resposta de uma forneça a resposta para a outra). Minha pesquisa no Google por 'c ++ onde está a definição size_t' me levou diretamente aqui, e eu teria perdido a outra pergunta, porque é diferente .
Os arquivos stdlib.he stddef.hheader definem um tipo de dados chamado size_t1, que é usado para representar o tamanho de um objeto. As funções de biblioteca que aceitam tamanhos esperam que sejam do tipo size_te o operador sizeof avalia comosize_t .
O tipo real de size_tdepende da plataforma; um erro comum é assumir que size_té o mesmo que int não assinado, o que pode levar a erros de programação, 2 especialmente quando as arquiteturas de 64 bits se tornam mais prevalentes.
Isso é exatamente o que eu precisava, essa resposta deve ser votada.
Neodefi
27
size_t é o tipo inteiro não assinado do resultado do operador sizeof (ISO C99, seção 7.17.)
O sizeofoperador gera o tamanho (em bytes) de seu operando, que pode ser uma expressão ou o nome entre parênteses de um tipo. O tamanho é determinado a partir do tipo do operando. O resultado é um número inteiro. O valor do resultado é definido pela implementação e seu tipo (um tipo inteiro não assinado) é size_t(ISO C99, Seção 6.5.3.4).
@ Martin - é verdade, mas acho que a parte da pergunta 'por que não é assinado?' É tão interessante (ou mais) quanto a parte 'o que é tamanho_t', e você não encontrará isso no padrão .
22909 Michael Burr
Sim, exceto que não há 'Seção 17.17 ': p. É raro, ninguém disse uma palavra sobre Void_t
Eliseo Ocampos
Aceito esta resposta, pois responde diretamente à pergunta, mas seria ótimo se fosse complementada com a resposta de Michael.
Eliseo Ocampos
58
Pena que sua resposta não me diga qual arquivo de cabeçalho incluir.
Matt
6
Na prática, size_trepresenta o número de bytes que você pode endereçar. Nas arquiteturas mais modernas dos últimos 10 a 15 anos, foram 32 bits, o que também tem o tamanho de um int não assinado. No entanto, estamos migrando para o endereçamento de 64 bits, enquanto o uintmais provável é permanecer em 32 bits (seu tamanho não é garantido no padrão c ++). Para tornar seu código que depende do tamanho da memória portátil entre arquiteturas, você deve usar a size_t. Por exemplo, coisas como tamanhos de matriz sempre devem usar size_t's. Se você observar os contêineres padrão, ::size()sempre retornará a size_t.
Observe também que o visual studio possui uma opção de compilação que pode verificar esses tipos de erros chamados "Detectar problemas de portabilidade de 64 bits".
Dessa forma, você sempre sabe qual é o tamanho, porque um tipo específico é dedicado aos tamanhos. A própria pergunta mostra que pode ser um problema: é um intou um unsigned int? Além disso, qual é a magnitude ( short, int, long, etc.)?
Como existe um tipo específico atribuído, você não precisa se preocupar com o comprimento ou a assinatura.
size_tcorresponde ao tipo de dados integral retornado pelo operador de idioma sizeofe é definido no<cstring> arquivo de cabeçalho (entre outros) como um tipo integral não assinado.
Em <cstring>, é usado como o tipo do parâmetro numnas funções memchr,memcmp , memcpy, memmove, memset, strncat, strncmp, strncpye strxfrm, que, em todos os casos, é usado para especificar o número máximo de bytes ou caracteres a função tem que afectar.
Ele também é usado como o tipo de retorno para strcspn, strlen,strspn e strxfrmpara tamanhos de retorno e comprimentos.
size_t deve ser definido nos cabeçalhos da sua biblioteca padrão. Na minha experiência, geralmente é simplesmente um typedef para unsigned int. O ponto, porém, é que não precisa ser. Tipos como size_t permitem ao fornecedor da biblioteca padrão a liberdade de alterar seus tipos de dados subjacentes, se apropriado para a plataforma. Se você assumir que size_t é sempre sem assinatura int (por meio de vazamento, etc), poderá ter problemas no futuro se o seu fornecedor alterar size_t para, por exemplo, um tipo de 64 bits. É perigoso assumir algo sobre esse ou qualquer outro tipo de biblioteca por esse motivo.
Os vários xxx_t typedefs são usados para abstrair um tipo de uma implementação definida específica, pois os tipos concretos usados para certas coisas podem diferir de uma plataforma para outra. Por exemplo:
size_t abstrai o tipo usado para armazenar o tamanho dos objetos, porque em alguns sistemas esse será um valor de 32 bits; em outros, pode ser de 16 ou 64 bits.
Void_tabstrai o tipo de ponteiro retornado pelas vmallocrotinas da biblioteca porque foi gravado para funcionar em sistemas anteriores à ANSI / ISO C, em que ovoid palavra chave pode não existir. Pelo menos é o que eu acho.
wchar_t abstrai o tipo usado para caracteres largos, já que em alguns sistemas será do tipo 16 bits, em outros será de 32 bits.
Portanto, se você escrever seu código de manipulação de caracteres amplo para usar o wchar_ttipo em vez de, digamos unsigned short, esse código provavelmente será mais portátil para várias plataformas.
Isto é o que eu estava procurando, em parte. Como eu disse em um comentário em resposta de fpmurphy, seria ótimo que ele pode ser complementado com esta resposta (Se você não se importa talvez você possa editá-lo) :)
Eliseo Ocampos
1
Em programas minimalistas em que uma size_tdefinição não foi carregada "por acaso" em algumas inclusões, mas eu ainda a necessito em algum contexto (por exemplo, para acessar std::vector<double>), então uso esse contexto para extrair o tipo correto. Por exemplotypedef std::vector<double>::size_type size_t .
(Coloque, namespace {...}se necessário, para tornar o escopo limitado.)
Quanto a "Por que não usar int ou unsigned int?", Simplesmente porque é semanticamente mais significativo não usar. Existe a razão prática de que ele pode ser, digamos, typedefd como inte depois atualizado para um longposterior, sem que ninguém precise alterar seu código, é claro, mas mais fundamentalmente do que um tipo deve ser significativo. Para simplificar bastante, uma variável do tipo size_té adequada e usada para conter os tamanhos das coisas, assim como time_té adequada para conter valores temporais. Como elas são realmente implementadas deve ser o trabalho da implementação. Comparado a apenas chamar tudo int, o uso de nomes de tipos significativos como esse ajuda a esclarecer o significado e a intenção do seu programa, assim como qualquer tipo rico de tipos.
Respostas:
Da Wikipedia
Desde C99 7.17.1 / 2
fonte
int
e osunsigned int
tipos são 32 bits, enquanto size_t é 64 bits.De acordo com size_t, a descrição em pt.cppreference.com
size_t
é definida nos seguintes cabeçalhos:fonte
size_t
é o tipo inteiro não assinado do resultado do operador sizeof (ISO C99, seção 7.17.)O
sizeof
operador gera o tamanho (em bytes) de seu operando, que pode ser uma expressão ou o nome entre parênteses de um tipo. O tamanho é determinado a partir do tipo do operando. O resultado é um número inteiro. O valor do resultado é definido pela implementação e seu tipo (um tipo inteiro não assinado) ésize_t
(ISO C99, Seção 6.5.3.4).fonte
Na prática,
size_t
representa o número de bytes que você pode endereçar. Nas arquiteturas mais modernas dos últimos 10 a 15 anos, foram 32 bits, o que também tem o tamanho de um int não assinado. No entanto, estamos migrando para o endereçamento de 64 bits, enquanto ouint
mais provável é permanecer em 32 bits (seu tamanho não é garantido no padrão c ++). Para tornar seu código que depende do tamanho da memória portátil entre arquiteturas, você deve usar asize_t
. Por exemplo, coisas como tamanhos de matriz sempre devem usarsize_t
's. Se você observar os contêineres padrão,::size()
sempre retornará asize_t
.Observe também que o visual studio possui uma opção de compilação que pode verificar esses tipos de erros chamados "Detectar problemas de portabilidade de 64 bits".
fonte
Dessa forma, você sempre sabe qual é o tamanho, porque um tipo específico é dedicado aos tamanhos. A própria pergunta mostra que pode ser um problema: é um
int
ou umunsigned int
? Além disso, qual é a magnitude (short
,int
,long
, etc.)?Como existe um tipo específico atribuído, você não precisa se preocupar com o comprimento ou a assinatura.
A definição real pode ser encontrada na Biblioteca de Referência C ++ , que diz:
fonte
size_t deve ser definido nos cabeçalhos da sua biblioteca padrão. Na minha experiência, geralmente é simplesmente um typedef para unsigned int. O ponto, porém, é que não precisa ser. Tipos como size_t permitem ao fornecedor da biblioteca padrão a liberdade de alterar seus tipos de dados subjacentes, se apropriado para a plataforma. Se você assumir que size_t é sempre sem assinatura int (por meio de vazamento, etc), poderá ter problemas no futuro se o seu fornecedor alterar size_t para, por exemplo, um tipo de 64 bits. É perigoso assumir algo sobre esse ou qualquer outro tipo de biblioteca por esse motivo.
fonte
Não estou familiarizado,
void_t
exceto como resultado de uma pesquisa no Google (é usada em umavmalloc
biblioteca por Kiem-Phong Vo na AT&T Research - tenho certeza de que também é usada em outras bibliotecas).Os vários xxx_t typedefs são usados para abstrair um tipo de uma implementação definida específica, pois os tipos concretos usados para certas coisas podem diferir de uma plataforma para outra. Por exemplo:
Void_t
abstrai o tipo de ponteiro retornado pelasvmalloc
rotinas da biblioteca porque foi gravado para funcionar em sistemas anteriores à ANSI / ISO C, em que ovoid
palavra chave pode não existir. Pelo menos é o que eu acho.wchar_t
abstrai o tipo usado para caracteres largos, já que em alguns sistemas será do tipo 16 bits, em outros será de 32 bits.Portanto, se você escrever seu código de manipulação de caracteres amplo para usar o
wchar_t
tipo em vez de, digamosunsigned short
, esse código provavelmente será mais portátil para várias plataformas.fonte
Em programas minimalistas em que uma
size_t
definição não foi carregada "por acaso" em algumas inclusões, mas eu ainda a necessito em algum contexto (por exemplo, para acessarstd::vector<double>
), então uso esse contexto para extrair o tipo correto. Por exemplotypedef std::vector<double>::size_type size_t
.(Coloque,
namespace {...}
se necessário, para tornar o escopo limitado.)fonte
Quanto a "Por que não usar int ou unsigned int?", Simplesmente porque é semanticamente mais significativo não usar. Existe a razão prática de que ele pode ser, digamos,
typedef
d comoint
e depois atualizado para umlong
posterior, sem que ninguém precise alterar seu código, é claro, mas mais fundamentalmente do que um tipo deve ser significativo. Para simplificar bastante, uma variável do tiposize_t
é adequada e usada para conter os tamanhos das coisas, assim comotime_t
é adequada para conter valores temporais. Como elas são realmente implementadas deve ser o trabalho da implementação. Comparado a apenas chamar tudoint
, o uso de nomes de tipos significativos como esse ajuda a esclarecer o significado e a intenção do seu programa, assim como qualquer tipo rico de tipos.fonte