Qui en-tête dois-je inclure pour " size_t`?
Selon cppreference.com size_t
est définie de plusieurs en-têtes, à savoir
<cstddef>
<cstdio>
<cstring>
<ctime>
Et, depuis C++11, également dans
<cstdlib>
<cwchar>
Tout d'abord je me demande pourquoi c'est le cas. N'est-ce pas en contradiction avec la SEC principe? Cependant, ma question est:
Dont l'un des au-dessus des en-têtes dois-je inclure pour utiliser size_t
? Importe-t-il à tous?
- Ouvert correspondant fichiers d'en-tête et de trouver la définition.
- C'est une excellente façon d'écrire fragile du code non portable!
- Ne pas vraiment comprendre, j'ai tout à fait confiance qu'elle est définie dans les en-têtes
- Tous ces en-têtes sont C-têtes. Ils sont nécessaires si vous appelez les fonctions C au lieu de leur C++ équivalents. Vous ne devriez probablement pas l'utiliser et trouver le C++ équivalents de
- C-têtes qui font partie de la norme C++ de la bibliothèque et ne sont probablement pas dupliquer dans l'un de vos allégations de "vrai C++" en-têtes. Quel a été votre point de vue, exactement?
- J'ai toujours utilisé
<cstddef>
pourstd::size_t
- Ouais, je suis (de manière informelle) assez sûr que ce soit le lieu pour cela, même si elle finit par être inclus dans les autres.
- de ne pas mentionner aucun "vrai" en-têtes, mais à l'aide de fonctions C quand il y a des C++ équivalents de ne causer de problème. Par exemple, le mélange de la chaîne d'en-têtes
- Demander, dans la pour tout ce qui n'est pas de meilleure façon d'écrire du code portable.
- Je sais, j'étais sarcastique!
- Bien sûr, en général c'est un bon conseil, mais dans ce cas, il ne semble pas pertinent - comme il n'y a pas de C++ de remplacement pour
std::size_t
, et l'OP n'était pas plaider en utilisant l'héritage de fonctions C, en observant la citation sur eux le partage de la définition de type. Je doute que quiconque la lecture de ce thread serait induit en erreur en utilisant les anciens types de fonctions à cause de cela, mais si vous voulez être sûr qu'ils ne le font pas, juste assez! - Double Possible de What est la différence entre un size_t et int en C++?
- pas vraiment clair à mes pourquoi vous pensez que c'est un dupe. Je sais quelle est la diff entre
int
etsize_t
(et je le savais déjà quand vous posez la question). Les réponses acceptées il y a aussi mentionne seulement deux en-têtes de le définir, mais il ne dit pas lequel de ceux à qui l'on doit utiliser - en fait la accepté de répondre à cette question, ne mentionne que le c-têtes, mais bien sûr, je préfère le c++ en-têtes
- excellente question. J'ai également été intrigué par ce peu de temps en arrière. +1 pour cette
Vous devez vous connecter pour publier un commentaire.
En supposant que je voulais minimiser les fonctions et les types I importait, j'irais avec
cstddef
comme il ne veut pas déclarer toutes les fonctions et ne déclare qu'6 types. Les autres se concentrent sur des domaines particuliers (chaînes de caractères, le temps, IO) qui ne peut pas d'importance pour vous.Noter que
cstddef
seulement des garanties à définirstd::size_t
, c'est la définition desize_t
dans l'espace de nomsstd
, bien qu'il peut fournir ce nom dans l'espace de noms global (en fait, plainesize_t
).En revanche,
stddef.h
(qui est également un en-tête disponible en C) des garanties pour définirsize_t
dans l'espace de noms global, et peut également fournirstd::size_t
.size_t
decstddef
est la même et sera toujours le même que les autres? Semble comme il devrait être un bon fichier d'en-tête avec des définitions communes commesize_t
...cstddef
.<cstddef>
, ou ils peuvent inclure tous les internes en tête, qui ne définitsize_t
.size_t
dans<cstddef>
est la même que dans les autres en-têtes, ce genre d'idiots ne vous prenez la bibliothèque des graphistes? Il est défini dans<cstddef>
, mais peuvent également être disponibles (directement ou indirectement) en incluant d'autres en-têtes.size_t
de différents en-têtes, sauf si vous avez délibérément ou par négligence cassé de votre compilateur. Choses sera toujours le même pour une application donnée. Le type d'unsizeof
expression n'est pas juste varient en fonction du jour de la semaine. Si vous doutez encore que les, prendre de quelqu'un qui en fait met en œuvre la bibliothèque standard pour une vie que c'est vrai, et vous pouvez compter sur elle être la même dans chacun de ces en-têtes.<ctime>
définit des fonctions commestrftime
qui utilisentsize_t
dans leur interface, et<cstring>
définit des fonctions commememcpy
qui utilisentsize_t
dans leur interface, c'est débile poursize_t
être définies à la suite notamment de ceux en-têtes? Je ne pense pas que vous avez pensé à ce travers.csttddef
dans la réponse à une faute de frappe? Peut-êtrecstddef
est destinée?En fait le synopsis (inclus dans la norme C++) de plusieurs en-têtes specifially inclure
size_t
ainsi que d'autres en-têtes de définir le typesize_t
(basé sur la norme C comme le<cX>
les en-têtes sont juste ISO C<X.h>
les en-têtes de avec a noté des changements où la suppression desize_t
n'est pas indiqué).La norme C++ cependant, se réfère à
<cstddef>
pour la définition destd::size_t
Par conséquent, et en raison du fait que
<cstddef>
seulement introduit les types et les fonctions, je collerais à cet en-tête pour fairestd::size_t
disponibles.De noter quelques petites choses :
Le type de
std::size_t
est obtenu à l'aide dedecltype
sans y inclure un en-têteSi vous avez l'intention d'introduire une définition de type dans votre code, de toute façon (c'est à dire parce que vous écrivez un récipient et souhaitez proposer un
size_type
typedef), vous pouvez utiliser le mondialsizeof
,sizeof...
oualignof
opérateurs pour définir votre type sans y inclure les en-têtes à tous, depuis ces opérateurs retourstd::size_t
par définition standard et vous pouvez utiliserdecltype
sur eux:std::size_t
est pas en soi le monde visible, bien que les fonctions avecstd::size_t
arguments.La déclarées implicitement mondial de l'allocation et la libération des fonctions
ne PAS introduire de
size_t
,std
oustd::size_t
etL'utilisateur ne peut pas redéfinir
std::size_t
bien qu'il est possible d'avoir plusieurs typedefs référence au même type dans le même espace de noms.Bien que, la survenue de multiples définitions de
size_t
dansstd
est parfaitement valide que par 7.1.3 /3, il n'est pas autorisé à ajouter des déclarations denamespace std
comme par 17.6.4.2.1 /1:L'ajout d'une bonne définition de type de
size_t
à l'espace de noms ne viole pas 7.1.3 mais il ne viole 17.6.4.2.1 et conduit à un comportement indéterminé.Précisions: Essayez de ne pas mal interpréter 7.1.3 et n'ajoutez pas de déclarations ou de définitions de
std
(à l'exception de quelques le modèle de la spécialisation des cas où un typedef n'est pas un modèle de spécialisation). L'extension de lanamespace std
std
est pas valide car en double typedefs sont illégales. Je déclare que c'est illégal parce que vous simplement ne pouvez pas ajouter des définitions denamespace std
- peu importe si ils sont légaux.std::size_t
est du même type que::size_t
qui est du même type que le résultat desizeof(1)
alors comment pourrait-il en être légèrement différente de la définition? Si c'est le cas, la mise en œuvre est non conforme.Tous les standard de la bibliothèque de fichiers d'en-tête ont la même définition; il n'est pas question que l'un de vous inclure dans votre propre code. Sur mon ordinateur, j'ai la déclaration suivante dans
_stddef.h
. Ce fichier est inclus par tous les fichiers que vous avez énumérés.size_t
en premier lieu?size_t
. Vous pouvez définir plus portably commeusing size_t = decltype( sizeof( 42 ) )
. Mais il n'est pas nécessaire, puisque<stddef.h>
a presque zéro coût.Vous pourriez le faire sans en-tête:
C'est parce que la norme C++ nécessite:
En d'autres termes, la norme exige:
Également noter qu'il est parfaitement bien de faire ce
typedef
déclaration dans le mondial et dansstd
espace de noms, tant qu'il correspond à tous les autrestypedef
déclarations de la même typedef-nom (une erreur du compilateur est délivrée sur la non-correspondance des déclarations).C'est parce que:
§7.1.3.1 Un typedef-nom ne pas introduire un nouveau type de la façon dont une déclaration de classe (9.1) ou déclaration d'enum n'.
§7.1.3.3 Dans un non-étendue de classe, un
typedef
spécificateur peut être utilisé pour redéfinir le nom de n'importe quel type déclaré dans le champ d'application pour désigner le type à qui il fait déjà référence.Pour les sceptiques disent que cela constitue un ajout d'un nouveau type dans l'espace de noms
std
, et un tel acte est explicitement interdite par la norme, et c'est UB et c'est tous là pour ça; je dois dire que cette attitude élève à ignorer et nier meilleure compréhension des enjeux sous-jacents.La norme des interdictions de l'ajout de nouvelles déclarations et les définitions dans l'espace de noms
std
car, ce faisant, l'utilisateur peut faire un désordre de la bibliothèque standard et tirer sur sa jambe large. Pour les rédacteurs de normes, il était plus facile pour permettre à l'utilisateur de se spécialiser un peu de choses et l'interdiction de faire quoi que ce soit, pour faire bonne mesure, plutôt que d'interdire tous les seule chose que l'utilisateur ne doit pas faire au risque de manquer quelque chose d'important (et que la jambe). Ils l'ont fait dans le passé, lorsque exigeant qu'aucun conteneur standard doit être instancié avec un type incomplète, alors qu'en fait, certains conteneurs pourraient bien faire (voir La Norme Bibliothécaire: les Conteneurs sont Incomplètes Types de Matthew H. Austern):Étant donné que la langue règles exigent
std::size_t
être exactementdecltype(sizeof(int))
, fairenamespace std { using size_t = decltype(sizeof(int)); }
est une de ces choses qui ne cassent pas quoi que ce soit.Avant C++11 il n'y a pas de
decltype
et donc aucun moyen de déclarer le type desizeof
suite à une simple déclaration, sans faire une bonne affaire de modèles impliqués.size_t
alias de types différents sur différentes architectures cibles, cependant, il ne serait pas une solution élégante pour ajouter un nouveau type juste pour le résultat desizeof
, et il n'existe pas de standard intégré dans les typedefs. Par conséquent, la solution la plus compacte à l'époque était de mettresize_t
type alias dans un en-tête spécifique et document.En C++11, il est maintenant une façon d'écrire que l'exigence exacte de la norme comme un simple déclaration.
size_t
que je voudrais évitersize_t
est défini n'est pas signé, et pourtant, vous avez défini est commesigned
. La montre le problème avec le fait d'essayer de couper et de coller votre chemin autour de l'utilisation de la norme en-têtes de!::size_t
typedef. Vous pouveztypedef
le même type de nombreuses fois, aussi longtemps qu'il est mappé sur le même type.size_t
est définie par le système. Pourquoi devrait-il êtreint
?size_t
est pas signé.size_t
!" Une minute plus tard, Marie dit, "OMG! Il y a 7 définitions desize_t
à travers la bibliothèque standard les en-têtes et un projet d'en-tête de Tom est de l'édition! Il y a probablement plus dans la 3e partie des bibliothèques!" xkcd.com/927sizeof
estsize_t
. Ce code introduit un type, qui est égal au type de retour desizeof
, et les noms quisize_t
.std::size_t
définition de toute façon depuis l'ajout destd
n'est pas autorisée. Mais en fonction de ce que vous faites (c'est à dire la mise en œuvre de certains type de Conteneur de la définition d'unsize_type
), vous pouvez introduire une nouvelle définition de type et puis, cette réponse est valable pour le faire.using size_t = decltype(sizeof(1));
, lol.std::
. Il est parfaitement acceptable de présenter les choses commemylib::binary_tree::size_type
. Je me sens douteux de définir le 7e mondialsize_t
quand il y a 6std::size_t
disponibles.std
et je pense que les typedefs ne sont pas autorisés. Ce n'est pas à propos de l'ODR.std
, ni redéfinit tout type, simplement une déclaration en double. Cela ne veut pas casser l'ODR. Totalement inoffensif..
Cela inclut les déclarations en double.std::size_t
de toute façon et comme vous n'ajoutez pas "un autre"std::size_t
comme @NickyC donne à penser, mais plutôt unsize_t
(espérons-le) dans votre environnement local.std
. Il n'y a pas d'exception pour la copie des déclarations et, par conséquent, ils sont formellement interdits dans les régimes, en respectant le code C++.namespace std
.std
ici.size_t
, cela ne veut pas répondre à l'OP de la vraie question: c'est comme si je l'avais demandé pour l'en-tête oùFILE
est déclarée et que vous souhaitez suggérer d'écrire la mienne.size_t
dansnamespace std
, l'OP question était à propos de l'obtention de l'accès àstd::size_t
. De sorte qu'il ne soit pas répondre à l'OP de la question, ou conseille UB pour le faire. (Injection d'une telle définition de type dansnamespace std
est une déclaration, et vous ne pouvez pas ajouter une déclaration d'espace de nomsstd
.) Votre insistance sur le fait que ce qui est légal n'est pas pertinente: même si vous correcte, la norme devrait être au moins ambigu de l'AC, et l'ajout d'une manière ambiguë, UB du code est presque aussi mauvais que sans ambiguïté UB, sauf grande récompense.std::string::data()
comme contiguë, lorsque la norme n'exige pas ou de la garantie de cette qualité. Basé sur les précédents historiques, et les exigences de la norme layed dehors dans ce post, la probabilité de cet être UB est de 0.std
autres que dans quelques cas précis ne doit pas être fait par l'utilisateur code côté. Ce n'est pas une underspecification. Vous semblez faire valoir "bien sûr, la norme dit de ne pas le faire, mais le faire de toute façon, qu'est-ce que le mal". C'est fondamentalement différente de celle de "le standard a une erreur". Enfin, en supposant questd::string::data()
était contiguë a une grande récompense, votre suggestion aucun.-7
(sans doute) parce que les gens ne comprennent pas quedecltype(sizeof(int))
était fondamentalementsize_t
, pasint
. D'autres coupant les cheveux en quatre questions n'étaient pas dans mon périmètre.std
UB. Et il n'y a que vous venez de désaccord avec cela. Tous plaident pour une réponse au meilleur résout pas de problème de toute façon et il est juste d'essayer d'être intelligent. Dans le meilleur des cas, vous avez raison (et vous n'êtes pas), et c'est une mauvaise réponse. Le pire des cas, c'est tout simplement faux.std::size_t
définition, ce dernier ne fonctionne pas.std::size_t
. Mais dans ce cas, il ne sera jamais rien de mal, parce quedecltype(sizeof 1)
eststd::size_t
. Mais je ne vois aucun avantage à le faire plutôt que de#include <cstddef>
(qui est un tout petit en-tête).