Est-ce que “std :: size_t” a du sens en C ++?

Dans certains codes dont j’ai hérité, je vois fréquemment l’utilisation de size_t avec le qualificatif std espace de noms. Par exemple:

 std::size_t n = sizeof( long ); 

Il comstack et fonctionne bien, bien sûr. Mais cela me semble une mauvaise pratique (peut-être reporté de C?).

N’est-il pas vrai que size_t est intégré à C ++ et donc à l’espace de noms global? Un fichier d’en-tête est-il nécessaire pour utiliser size_t en C ++?

Une autre façon de poser cette question est la suivante: le programme suivant ( sans inclusion) devrait-il être compilé sur tous les compilateurs C ++?

 size_t foo() { return sizeof( long ); } 

Il semble y avoir une confusion parmi la foule de stackoverflow à ce sujet

::size_t est défini dans l’en-tête de compatibilité descendante stddef.h . Cela fait partie de ANSI/ISO C et ISO C++ depuis leurs débuts. Chaque implémentation C ++ doit être stddef.h avec stddef.h (compatibilité) et cstddef où seul ce dernier définit std::size_t et pas nécessairement ::size_t . Voir l’annexe D de la norme C ++.

La section 17.4.1.2 de la norme C ++, paragraphe 4, stipule que:

“Toutefois, dans la bibliothèque standard C ++, les déclarations et les définitions (à l’exception des noms définis en tant que macros en C) se trouvent dans la scope de l’espace de noms (3.3.5) de l’espace de noms std.”

Cela inclut les éléments trouvés dans les en-têtes du modèle cname , y compris cstddef , qui définit size_t.

Donc std :: size_t est en fait correct.

Vous pouvez obtenir size_t dans l’espace de noms global en incluant, par exemple, au lieu de . Je ne vois aucun avantage évident et la fonctionnalité est obsolète.

size_t n’est pas intégré à C ++. Et ce n’est pas défini par défaut. Celui-ci ne comstack pas avec GCC:

 int main(int argc, char** argv) { size_t size; } 

Cela dit, size_t fait partie de POSIX et si vous n’utilisez que des éléments basiques comme , vous probablement par le définir.

Vous pourriez soutenir que std :: size_t est l’équivalent en C ++ de size_t. Comme Brian l’a souligné, std :: est utilisé comme espace de noms pour éviter de définir des variables globales qui ne correspondent pas à tout le monde. C’est comme std :: ssortingng, qui pourrait également avoir été défini dans l’espace de noms racine.

 std::size_t n = sizeof( long ); 

En fait, vous n’avez pas demandé ce qui semble être une mauvaise pratique dans ce qui précède. Utilisation de size_t, qualification avec std namespace, …

Comme le dit le standard C ++ (18.1), size_t est un type défini dans l’en-tête standard. Je suggère de laisser tomber toutes les pensées et les impressions sur l’inheritance possible du langage C. C ++ est un langage distinct et différent, il est préférable de le considérer comme tel. Il possède sa propre bibliothèque standard et tous les éléments de la bibliothèque standard C ++ sont définis dans namespace std. Cependant, il est possible d’utiliser des éléments de la bibliothèque standard C dans le programme C ++.

J’envisagerais d’inclure comme un hack sale. Le standard C ++ stipule que le contenu des en-têtes est identique ou basé sur les en-têtes correspondants de la bibliothèque standard C, mais dans un certain nombre de cas, des modifications ont été appliquées. En d’autres termes, ce n’est pas un copier-coller direct des en-têtes C dans les en-têtes C ++.

size_t n’est pas un type intégré en C ++. C’est un type défini pour spécifier quel type de type intégral est utilisé comme type de retour de l’opérateur sizeof (), car un type de retour réel de sizeof () est défini par l’implémentation, de sorte que le standard C ++ unifie en définissant size_t.

le programme suivant (sans inclusion) devrait-il être compilé sur tous les compilateurs C ++?

 size_t foo() { return sizeof( long ); } 

Le standard C ++ dit (1.4):

Les noms définis dans la bibliothèque ont une scope d’espace de noms (7.3). L’unité de traduction AC ++ (2.1) obtient l’access à ces noms en incluant l’en-tête de bibliothèque standard approprié (16.2).

La taille_t est un nom défini dans l’espace de noms std, donc chaque programme qui utilise ce nom doit inclure l’en-tête correspondant, dans ce cas.

Ensuite, le chapitre 3.7.3 dit:

Cependant, se référant à std, std :: bad_alloc et std :: size_t est mal formé à moins que le nom ait été déclaré en incluant l’en-tête approprié.

Étant donné que le programme utilisant size_t mais sans inclure l’en-tête est mal formé.

Parfois, d’autres bibliothèques définiront leur propre taille_t. Par exemple, boost. std :: size_t spécifie que vous voulez définitivement le standard c ++.

size_t est un type standard c ++ défini dans l’espace de noms std.

Les en-têtes du compilateur GNU contiennent quelque chose comme

  typedef long int __PTRDIFF_TYPE__;
 typedef unsigned long int __SIZE_TYPE__; 

Alors stddef.h contient quelque chose comme

  typedef __PTRDIFF_TYPE__ ptrdiff_t;
 typedef __SIZE_TYPE__ size_t; 

Et enfin le fichier cstddef contient quelque chose comme

 #include 

 espace de noms std {

   using :: ptrdiff_t;
   using :: size_t;

 }

Je pense que cela devrait le rendre clair. Tant que vous incluez , vous pouvez utiliser soit size_t soit std :: size_t car size_t a été typé en dehors de l’espace de noms std et a ensuite été inclus. Effectivement vous avez

  typedef long int ptrdiff_t;
 typedef unsigned long int size_t;

 espace de noms std {

   using :: ptrdiff_t;
   using :: size_t;

 }

Je pense que les clarifications sont suffisamment claires. Le std::size_t fait du bon sens en C ++ et ::size_t rend (au moins) bon sens en C.

Cependant, une question rest. À savoir s’il est sûr de supposer que ::size_t et std::size_t sont compatibles?

D’un sharepoint vue purement typé, ils ne sont pas nécessairement identiques à moins d’être définis quelque part qu’ils doivent être identiques.

Je pense que beaucoup utilisent quelque chose à la:

 ---- // a.hpp #include  void Foo( const std::ssortingng & name, size_t value ); ----- // a.cpp #include "a.hpp" using namespace std; void Foo( const ssortingng & name, size_t value ) { ... } 

Donc, dans l’en-tête, vous utilisez le ::size_t alors que dans le fichier source, vous utiliserez std::size_t . Ils doivent donc être compatibles, non? Sinon, vous aurez une erreur de compilation.

/ Michael S.