size_t vs int avertissement

Je reçois toujours l’avertissement suivant pour le type de code suivant.

std::vector v; for ( int i = 0; i < v.size(); i++) { } 

warning C4267: 'initializing' : conversion from 'size_t' to 'int', possible loss of data

Je comprends que size() renvoie size_t , je voulais juste savoir si cet avertissement est sûr ou devrais-je faire toute la variable loop de type size_t

Si vous avez besoin de contenir plus d’éléments INT_MAX dans votre vecteur, utilisez size_t . Dans la plupart des cas, cela n’a pas vraiment d’importance, mais j’utilise size_t juste pour que l’avertissement disparaisse.

Mieux encore, utilisez les iterators:

 for( auto it = v.begin(); it != v.end(); ++it ) 

(Si votre compilateur ne supporte pas C ++ 11, utilisez std::vector::iterator à la place de auto )

C ++ 11 facilite également le choix du meilleur type d’index (au cas où vous utiliseriez l’index dans certains calculs, et pas uniquement pour l’indexation v ):

 for( decltype(v.size()) i = 0; i < v.size(); ++i ) 

Qu’est-ce que la size_t ?
size_t correspond au type de données intégral renvoyé par l’opérateur sizeof opérateur de langue et est défini dans le fichier d’en-tête (entre autres) en tant unsigned integral type .

Est-il correct de lancer size_t en int ?
Vous pouvez utiliser une dissortingbution si vous êtes certain que la taille ne sera jamais> que INT_MAX .

Si vous essayez d’écrire un code portable, ce n’est pas sûr car,

size_t en 64 bit Unix est de 64 bits
size_t en 64 bit Windows est de 32 bits

Donc, si vous portez votre code de Unix à Windows et que ci-dessus sont les environnements, vous perdrez des données.

Réponse suggérée

Compte tenu de la mise en garde, la suggestion est de faire i de unsigned integral type ou même mieux l’utiliser comme type size_t .

Est-ce sûr d’ignorer cet avertissement ou devrais-je faire toutes mes variables de boucle de type size_t

Vous vous ouvrez à une classe d’attaques de dépassement d’entier. Si la taille du vecteur est supérieure à MAX_INT (et qu’un attaquant peut y arriver), votre boucle s’exécutera pour toujours, provoquant une possibilité de déni de service.

Techniquement, std::vector::size renvoie std::vector::size_type , cependant.

Vous devez utiliser la bonne signature pour vos variables de compteur de boucle. (Vraiment, pour la plupart des utilisations, vous voulez des entiers non signés plutôt que des entiers signés pour les boucles)

Le problème est que vous mélangez deux types de données différents. Sur certaines architectures, size_t est un entier sur 32 bits, sur d’autres c’est sur 64 bits. Votre code doit gérer correctement les deux.

puisque size() retourne un size_t ( pas int ), alors ce devrait être le type de données auquel vous le comparez.

 std::vector v; for ( size_t i = 0; i < v.size(); i++) { } 

Voici une autre vue de Bjarne Stroustrup: http://www.stroustrup.com/bs_faq2.html#simple-program

 for (int i = 0; i 

Oui, je sais que je pourrais déclarer que je suis un vecteur :: size_type plutôt que simple int pour calmer les avertissements de certains compilateurs hyper-suspects, mais dans ce cas, je considère cela trop pédant et distrayant.

C'est un compromis. Si vous craignez que v.size () ne dépasse 2 147 483 647, utilisez size_t. Si vous utilisez i dans votre boucle pour plus que simplement regarder à l'intérieur du vecteur, et que vous êtes préoccupé par de subtiles bogues liés signés / non signés, utilisez int. D'après mon expérience, cette dernière question est plus répandue que la première. Votre expérience peut différer.

Voir aussi Pourquoi taille_t n'est-il pas signé? .