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?
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.
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.
Réponses:
Les C
size_t
et C ++std::size_t
sont 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,
Et le standard C ++ dit (à propos de l'en-
cstddef
tête) au §18.1 / 3,Alors oui, les deux sont identiques; la seule différence est que C ++ définit
size_t
dans l'std
espace 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:
Et le reste, vous pouvez le lire sur cette page sur wikipedia.
la source
size_t
sansusing namespace std;
ouusing std::size_t;
. Cependant, la plupart des compilateurs le permettent, et le Standard leur permet spécifiquement de le permettre (§D.5 / 3).<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.::size_t
est présent par exemple dans<stddef.h>
, vous n'avez donc pas toujours besoin de le qualifier avecstd::
.À partir de C ++ 03 "17.4.3.1.4 Types":
Et note 169:
la source
std::T
variantes définies?#include <stddef.h>
alors disponiblestd::size_t
ou non. Si vous êtes#include <cstddef>
alorsstd::size_t
disponible, maissize_t
peut-être pas.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 dansstd::
et de niveau supérieur. La plupart des compilateurs n'incluent que l'en-tête C et importent les noms dansstd::
, donc les symboles finissent par être définis dans les deux.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>
etsize_t
et je ne réfléchirais jamais à une secondestd::size_t
; en fait, il ne me vient jamais à l'esprit qu'il y a (ou pourrait y avoir) unstd::size_t
.std :: size_t est en fait le size_t de stddef.h .
cstddef donne ce qui suit:
... apportant efficacement la définition précédente dans l'espace de noms std.
la source
<cstddef>
et vous attendre à obtenir::size_t
, mais si vous incluez,<stddef.h>
vous obtiendrezstd::size_t
.<stddef.h>
ne vous obtiendra::size_t
.<cstddef>
vous êtes assuré d'obtenirstd::size_t
et vous pourriez également obtenir::size_t
(mais ce n'est pas garanti). Si vous incluez,<stddef.h>
vous êtes assuré d'obtenir::size_t
et vous pourriez également obtenirstd::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.