J'ai un fichier test.cpp qui ressemble à ceci: la compilation en 64 bits GCC avec le drapeau (ligne 2 est la ligne dans laquelle aucun avertissement n'est produit si Il produisit cependant des avertissements lorsque Gardant à l'esprit que je suis sur une machine de 64 bits (Linux), pourquoi l'avertissement de conversion de la signature de la consension et la taille de Note 1: Je voulais tester cela sous un autre compilateur, mais le site COMEAU est en panne et je n'ai accès à aucun autre compilateurs, donc je ne peux pas dire s'il s'agit d'un comportement compatible standard ou d'un bogue GCC. em> p> note 2: test.cpp est un exemple minimal d'un problème d'un problème "Real" C ++ Dossier que j'ai dans lequel le meilleur moyen pour moi de me débarrasser de l'avertissement était d'entourer la ligne offensante avec: em> p> -WSign-conversion code> produit l'avertissement : p>
nouveau code> est appelé). Il me semble étrange que GCC devrait donner à cet avertissement sur l'allocation d'une matrice, mais les choses suivantes sont même étrangères: p>
non signé Char * A = nouveau caractère non signé [(non signé Int) N]; Code> ne se débarrasse pas de l'avertissement, ni n'utilise
static_cast
f code> est défini avec la signature
VOID F (t N) code>, où
t code> est p>
t code> est un type d'entier signé Const inférieur à 64 bits. p> li>
ol>
n code> dans ce cas et pourquoi ne tape pas la coulée corrige le problème? P>
8 Réponses :
const int est une valeur signée, vous jetez une valeur signée à la valeur non signée. Donc, le compilateur génère un avertissement qui, dans certains cas, cette conversion pourrait entraîner des calculs incorrects. P>
int code> est également un type signé. Cependant, comme indiqué sur OP, si le paramètre est déclaré avec type
int code>, il n'y a pas d'avertissement. C'est le
const code> spécifiquement qui semble le déclencher. C'est le point clé de la question.
Eh bien sa conversion pour vous, mais son avertissement vous avertissant que la conversion qu'il effectue changera le signe de la valeur qu'il change sinon vous pourriez automatiquement perdre de la valeur et les bogues pourraient resultir que vous soyez simplement Casting d'un INT vers un INT non signé Cela peut changer la valeur du signe normalement si je suis passé dans l'opérateur des limites de la matrice, il ne ferait pas l'avertissement comme si vous aimez cette p>
Essayez Turing of the Drapeau de conversion que vous avez sur et voyez s'il le fait toujours que le drapeau est ce qui cause l'avertissement parce que c'est la chose qui fait la conversion p>
Je suppose que cela devra faire avec la façon dont les littéraux entier sont manipulés: lorsque vous écrivez
int myArray[10];
Le TL; DR: Si cela représente la taille de quelque chose, faites-en un Le problème est que le tableau std ::ze_t code>. p>
new code> prend comme paramètre de taille une valeur de type
std ::ze_t code>, qui est garanti par la norme comme un type intégré non signé, Comme en témoigne la plainte de la conversion du compilateur vers
Unsigné longtemps Int code>. C'est là que la conversion non signée Signée a lieu et la solution correcte (IMO) de résoudre le problème est simplement de donner le paramètre
n code> de fonction
f code> type
std ::ze_t code>. Cela supprime au moins l'avertissement avec GCC 4.6 pour X86_64 GNU / Linux. P>
Cela n'explique pas pourquoi aucun avertissement n'est produit dans les conditions énumérées au point 2 de ma question. En outre, qu'est-ce que "TL; DR" signifie?
@Ose je ne suis pas sûr. Je pense que la meilleure explication est @ Andreyt's, que c'est juste un ennemi (éventuellement intentionnel) de l'analyse de type de GCC. "TL; DR" signifie trop longtemps; Ne [ou n'a pas] lu. "
Le compilateur avertit, car le signe peut changer lors de la conversion d'une valeur non signée. p>
1. Remplacer la ligne d'incrimination avec un caractère non signé * A = nouveau caractère non signé [(long non signé INT) N]; ne se débarrasse pas de l'avertissement, ni n'utilise static_cast (). P> blockQuote>
Le problème de la conversion de signe persiste, vous venez de le rendre explicite. Je suppose que c'est que ce n'est toujours pas assez explicite pour que le compilateur vous croie. Il croit toujours que vous avez déclaré
n code> a signé em>
const int code> pour une raison! P>
2. Aucun avertissement n'est produit si F est défini avec la signature Void F (t N), où T est P>
1. Tout type d'entier non-const, signé ou non signé de toute taille p> blockQuote> blockQuote>
si
n code> est non-const, il pourrait être em> le code entre le début de la fonction et la conversion, qui garantissait que N était positif, comme
n = (long non signé INT) (n); code>. Il semble que le compilateur vous donne le profit du doute dans ce cas et donc ne prépare donc pas. Quand il est déclaré em> déclaré const, le compilateur sait certainement qu'il s'agit d'un
int code> et avertit. p>
J'admets, mes explications ne ressemblent pas à quelque chose que g ++ ferait généralement. P>
Le problème réside dans la signature de votre fonction - le compilateur ferait une conversion implicite lorsque vous passez la Vous pouvez essayer de remplacer le type d'argument comme
Je suis un peu floconneux sur les détails, mais il me semble que le problème est en réalité dans le signe l'extension em> (puisqueze_t est probablement un non signé longtemps sur votre système). Considérez le code suivant: test.cpp: In function ?int main()?:
test.cpp:8:27: warning: conversion to ?long unsigned int? from ?const int? may change the sign of the result [-Wsign-conversion]
char* bp = new char [b];
Aucun de cela ne explique pourquoi le compilateur n'émet pas l'avertissement lorsque le paramètre Taille de la matrice n'est pas constitué. Par exemple. Ajout Char * NP = Nouveau Char [N]; Code> à votre deuxième fragment de code ne produit pas d'avertissement supplémentaire.
std ::ze_t code> est couramment utilisé pour l'indexation du tableau et le comptage de boucle. Les programmes qui utilisent d'autres types, tels que Unsigné Int, pour l'indexation du tableau peuvent échouer, par exemple. Systèmes 64 bits Lorsque l'index dépasse
uint_max code> ou s'il s'appuie sur l'arithmétique modulaire 32 bits. Cliquez ici pour en savoir plus sur STD :: Taille_T et 64 bits Systems < / p>
Merci pour votre contribution, mais cela ne répond pas non plus aux deux questions que j'ai posées. La meilleure réponse jusqu'à présent a été donnée par ant dans les commentaires ci-dessous la question.
Il vous avertit que si vous appelez
f (-1) code> vous pourriez être surpris.
Vous ne pouvez pas affecter une matrice de taille négative, il est donc probablement de convertir
n code> à une valeur non signée avant d'effectuer l'allocation. Changez votre paramètre en seulement
non signé INT N CODE> et voyez si l'avertissement disparaît.
@Petebecker ouais, mais pourquoi ne pas avertir dans d'autres cas similaires?
@Petebecker - Cela n'explique pas pourquoi il ne produit aucun avertissement lorsque je change la signature de F à vide F (INT N).
Je soupçonne que c'est la conversion en
Taille_T Code>, qui est probablement un TypeDef pour
Unsigned int code>.
@Ose - Vous demandez pourquoi le compilateur vous avertit de certaines erreurs courantes, mais pas toutes, moins courantes, de mauvais code?
C'est purement un avertissement "Knee Serk" - n'a rien à voir avec le
nouveau code> op, mais simplement avec la conversion impliquée de la conversion "n" au "type de paramètre" du
Nouveau code> op - Vous obtiendrez le même avertissement appelant une méthode avec le même type de parum. Et il s'agit d'avertissement que vous risquez de perdre la «signification» (de manière importante) sur la conversion signée -> non signée.
La raison pour laquelle il se produit uniquement pour
const code> est probablement à voir avec les paramètres qui transparent des conventions de ce compilateur. Probablement la plupart des INTS sont élargis à 64 bits, la conversion int -> longue est vraiment 64 bits -> longue, mais apparemment des valeurs constantes sont traitées différemment. Ces choses peuvent devenir assez vissues.
@Hotlicks - c'est intéressant. Savez-vous s'il y a une documentation de ces conventions de transmission de paramètres GCC?
Je m'attendrais à ce que les statiques échouent parce que vous ne pouvez pas utiliser static_cast pour jeter la constance.
@Seose - pas un indice. Je suis sûr qu'il y a une documentation quelque part, mais cela peut être un texte très cryptique dans un endroit très obscur.
@Bopersson - Je demande si une explication technique intéressante est une explication technique intéressante pour laquelle le compilateur traite les cas superficiellement similaires que j'ai décrits différemment, pour vous assurer que je n'ai pas mal compris quelque chose de fondamental sur le système de type C ++.
@Adrianmccarthy - Oh oui, bon point. Je suis sur le point de partir en vacances, mais quand je reviendrai, je verrai si static_cast fonctionne. Je serai surpris si c'est cependant, étant donné que la coulée de style C ne fonctionne pas.
@Seose - Je crois que la raison est simplement que l'équipe du compilateur a connu ou reçu des rapports de bogues, certains problèmes de conversion. Ils ont ensuite décidé d'ajouter des avertissements pour des choses que les gens se contractent souvent.
@Seose: Le problème a été signalé avant plusieurs fois. Ceci est juste une bizarrerie du compilateur GCC, quelque chose que vous devez vivre. J'imaginerais que les auteurs du compilateur comprenaient maintenant inutile cet avertissement sont dans certains contextes et ont fait un effort délibéré pour le supprimer dans de tels contextes. Mais ils ne les ont pas tous obtenus, c'est pourquoi vous voyez cet avertissement apparaît si incohérent.
@Andreyt Merci, cela ressemble à un candidat à une réponse acceptable. Avez-vous un lien vers un rapport de bogue ou GCC Changelog pour le sauvegarder?