Différence entre size_t et std :: size_t


139

Quelles sont les différences entre size_tet std::size_ten termes où ils sont déclarés, quand ils devraient être utilisés et d'autres caractéristiques de différenciation?


Je serais intéressé de savoir si la spécification C ++ lie std :: size_t au type C size_t.
Doug T.

Voir question similaire: lien
Mankarse

Réponses:


88

Les C size_tet C ++ std::size_tsont tous les deux identiques.

En C, il est défini dans <stddef.h>et en C ++, son <cstddef>contenu est le même que l'en-tête C (voir la citation ci-dessous). Il est défini comme un type entier non signé du résultat de l' opérateur sizeof .

C Standard dit au §17.7 / 2,

size_t qui est le type entier non signé du résultat de l' opérateur sizeof

Et le standard C ++ dit (à propos de l'en- cstddeftête) au §18.1 / 3,

Le contenu est le même que celui de l'en-tête de la bibliothèque Standard C, avec les modifications suivantes .

Alors oui, les deux sont identiques; la seule différence est que C ++ définit size_tdans l' stdespace de noms.

Veuillez également noter que la ligne ci-dessus indique également "avec les modifications suivantes", ce qui ne fait pas référence size_t. Il fait plutôt référence aux nouveaux ajouts (principalement) faits par C ++ dans le langage (non présents en C) qui sont également définis dans le même en-tête.


Wikipedia a de très bonnes informations sur la plage et la taille de stockage de size_t:

Plage et taille de stockage de size_t

Le type réel de size_t dépend de la plate-forme ; une erreur courante est de supposer que size_t est identique à unsigned int, ce qui peut conduire à des erreurs de programmation, [3] [4] lors du passage d'une architecture 32 à 64 bits, par exemple.

Selon la norme ISO C 1999 (C99), size_t est un type entier non signé d'au moins 16 bits.

Et le reste, vous pouvez le lire sur cette page sur wikipedia.


Cela amène à un autre Q, si STL importe déjà size_t via C (cstddef), pourquoi a-t-il à nouveau sa propre version?
Alok Sauvegardez le

43
@Als: Strictement parlant, c'est une erreur de dire size_tsans using namespace std;ou using std::size_t;. Cependant, la plupart des compilateurs le permettent, et le Standard leur permet spécifiquement de le permettre (§D.5 / 3).
Potatoswatter

9
@Potatoswatter: Cela ne peut certainement pas être à la fois une erreur et spécifiquement autorisé dans la norme? Si c'est dans la norme, ce n'est pas une erreur!
Ben Hymers

8
@BenHymers La norme spécifie ce que les en-têtes standard déclarent, et ils ne sont pas autorisés à déclarer d'autres noms non réservés. L'en-tête <cstddef>peut déclarer ou non ::size_t, vous ne pouvez donc pas vous fier à sa présence ou à son absence, à moins d'inclure spécifiquement <stddef.h>ou un autre en-tête de la bibliothèque C qui est garanti de le déclarer.
Potatoswatter

4
@Potatoswatter: Ah, je vois ce que tu veux dire maintenant! Je dois avoir été confus par trop de "permettre" dans une phrase. Je pense cependant que votre premier commentaire est trop fort; comme vous venez de le dire, ::size_test présent par exemple dans <stddef.h>, vous n'avez donc pas toujours besoin de le qualifier avec std::.
Ben Hymers

16

À partir de C ++ 03 "17.4.3.1.4 Types":

Pour chaque type T de la bibliothèque Standard C (note de bas de page 169), les types :: T et std :: T sont réservés à l'implémentation et, lorsqu'ils sont définis, :: T doit être identique à std :: T.

Et note 169:

Ces types sont clock_t, div_t, FILE, fpos_t, lconv, ldiv_t, mbstate_t, ptrdiff_t, sig_atomic_t, size_t, time_t, tm, va_list, wctrans_t, wctype_t et wint_t.


Le code portable ne devrait donc pas reposer sur les std::Tvariantes définies?
Mankarse

5
@Mankarse: Vous ne devriez pas vous fier à leur définition si vous incluez uniquement la version C de l'en-tête correspondant. Si vous êtes #include <stddef.h>alors disponible std::size_tou non. Si vous êtes #include <cstddef>alors std::size_tdisponible, mais size_tpeut-être pas.
Dennis Zickefoose

4
@Mankarse: l'oposite. Les versions C ++ des en-têtes doivent les définir dans std::et le paragraphe dit qu'il peut également les définir dans l'espace de noms de niveau supérieur et si c'est le cas, il doit les définir de manière identique dans std::et de niveau supérieur. La plupart des compilateurs n'incluent que l'en-tête C et importent les noms dans std::, donc les symboles finissent par être définis dans les deux.
Jan Hudec

4
Personnellement, je ne me soucie jamais des en-têtes <cxxxxx> ou des std::variantes d'identifiants qui proviennent de la rive C. Je m'en tiens aux <xxxxx.h>en-têtes C standard - cela n'a jamais été un problème. Donc, j'utiliserais <stddef.h>et size_tet je ne réfléchirais jamais à une seconde std::size_t; en fait, il ne me vient jamais à l'esprit qu'il y a (ou pourrait y avoir) un std::size_t.
Michael Burr

12

std :: size_t est en fait le size_t de stddef.h .

cstddef donne ce qui suit:

#include <stddef.h>
namespace std 
{
  using ::ptrdiff_t;
  using ::size_t;
}

... apportant efficacement la définition précédente dans l'espace de noms std.


Comme le souligne Nawaz, c'est en fait l'inverse. Vous ne pouvez pas inclure <cstddef>et vous attendre à obtenir ::size_t, mais si vous incluez, <stddef.h>vous obtiendrez std::size_t.
MSalters

4
@MSalters, je ne suis pas. Y compris <stddef.h>ne vous obtiendra ::size_t.
hifier

2
C'est donc un bogue dans votre implémentation.
MSalters

4
@MSalters, je ne suis pas tout à fait. Cela ne devrait-il pas être l'inverse? <cstddef> vient de C ++, donc devrait définir le truc dans std :: *? D'un autre côté, dans un en-tête C, comme stddef.h, je n'attendrais que le type C, c'est-à-dire :: size_t.
Ela782

11
@MSalters, depuis C ++ 11, ce n'est pas exact. Si vous incluez, <cstddef>vous êtes assuré d'obtenir std::size_tet vous pourriez également obtenir ::size_t(mais ce n'est pas garanti). Si vous incluez, <stddef.h>vous êtes assuré d'obtenir ::size_tet vous pourriez également obtenir std::size_t(mais ce n'est pas garanti). C'était différent en C ++ 03 mais c'était effectivement inimplémentable et corrigé comme un défaut.
Jonathan Wakely
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.