IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

 C Discussion :

Pourquoi la valeur de mon return n'est-elle pas illégale?


Sujet :

C

  1. #1
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Points : 12
    Points
    12
    Par défaut Pourquoi la valeur de mon return n'est-elle pas illégale?
    Bonjour, j'ai récemment recommencé à programmer en C et j'ai créé un petit programme bien simple qui convertit des valeurs décimales en nombres binaires. La fonction qui s'occupe de la conversion retourne une valeur de type unsigned long int. Étant donné le type retourné, mon programme ne convertis que les nombres inférieurs à 1023, (puisque la valeur maximale d'une variable de type unsigned long int est 4 294 967 295). Mais voilà, mon programme teste la valeur de son argument pour vérifier que celui-ci est bien inférieur à 1023, et si ce n'est pas le cas, il retourne -1. Pourtant, ma fonction est sensée retourner une valeur non-signée et mon compilateur ne me retourne aucune erreur ou avertissement. Le programme fonctionne très bien, mais je ne comprends pas pourquoi mon compilateur ne me retourne pas d'erreur ou d'avertissement... y'aurait-il une conversion implicite?

  2. #2
    Membre confirmé
    Inscrit en
    Juillet 2005
    Messages
    512
    Détails du profil
    Informations forums :
    Inscription : Juillet 2005
    Messages : 512
    Points : 641
    Points
    641
    Par défaut
    y'aurait-il une conversion implicite?
    Oui.
    Pourquoi il n'y a pas de warning ? Peut-être le compilateur est mal configuré !
    Sans code, je ne peux t'en dire plus.

  3. #3
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par Lucien63 Voir le message
    Oui.
    Pourquoi il n'y a pas de warning ? Peut-être le compilateur est mal configuré !
    Sans code, je ne peux t'en dire plus.
    Mon edi (Code:Blocks 10.05) utilise la configuration par défaut (avec MinGW utilisant GCC 4.5.2). Chose étonnante, normalement il me retourne un avertissement quand il y a conversion implicite.

    Pour ce qui est du code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    unsigned long int dec_to_binary(unsigned int iDecimal_value) {
     
    	unsigned long int iResult = 0;
     
    	int iBinary_value[10] = {0};
    	int i = 0;
     
        /* Étape 1 : on vérifie que le nombre n'est pas supérieur à 1022, sans quoi la valeur binaire dépasse la taille maximale
         * d'un entier non-signé de type long (4 294 967 295).
         */
    	if(iDecimal_value > 1022) {
    	    return -1;
    	}
     
     
    	/* Étape 2 : on effectue une conversion des bases grâce à l'opération de modulo, puis le nombre est divisé par 2. */
    	while(iDecimal_value != 0) {
    		iBinary_value[i] = iDecimal_value % 2;
    		iDecimal_value /= 2;
    		i++;
    	}
     
    	/* Étape 3 : on construit le nombre binaire en se servant de puissances de 10 */
    	for(i = 0; i<10; i++) {
    		iResult += iBinary_value[i] * pow(10,i);
    	}
     
    	return iResult;
    }
    Edit: J'ai même essayé en lignes de commande avec le flag -Wall.
    Edit 2: Avec -Wconversion, il me retourne un warning.

  4. #4
    Expert confirmé

    Inscrit en
    Août 2006
    Messages
    3 949
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 3 949
    Points : 5 665
    Points
    5 665
    Par défaut
    Lai,

    Je ne vois pas l'intérêt de ta fonction, mais je vois à qui tu veux l'utiliser : l'affichage en binaire.

    Si c'est bien le cas, tu fais fausse route : ton procédé te limite, en empêchant de gérer n'importe quelle valeur valide de ton paramètre iDecimal_value.
    La bonne démarche est alors de créer directement la chaîne de caractères représentant ta donnée, habituellement en fixant le nombre de caractères qui sera utilisé.

  5. #5
    Membre à l'essai
    Homme Profil pro
    Étudiant
    Inscrit en
    Juillet 2011
    Messages
    10
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Canada

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Juillet 2011
    Messages : 10
    Points : 12
    Points
    12
    Par défaut
    Citation Envoyé par droggo Voir le message
    Lai,

    Je ne vois pas l'intérêt de ta fonction, mais je vois à qui tu veux l'utiliser : l'affichage en binaire.

    Si c'est bien le cas, tu fais fausse route : ton procédé te limite, en empêchant de gérer n'importe quelle valeur valide de ton paramètre iDecimal_value.
    La bonne démarche est alors de créer directement la chaîne de caractères représentant ta donnée, habituellement en fixant le nombre de caractères qui sera utilisé.
    Merci, c'est bien noté, mais le but ici n'était que de me rafraîchir la mémoire quant aux notions de C que j'avais appris il y a quelques années, je me replonge dans les chaînes de caractère et je vais sûrement faire une nouvelle version de ce programme. D'ailleurs, c'est bien loin tout ça

  6. #6
    Expert éminent sénior
    Avatar de diogene
    Homme Profil pro
    Enseignant Chercheur
    Inscrit en
    Juin 2005
    Messages
    5 761
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Enseignant Chercheur
    Secteur : Enseignement

    Informations forums :
    Inscription : Juin 2005
    Messages : 5 761
    Points : 13 926
    Points
    13 926
    Par défaut
    La règle de conversion d'un type entier vers un type entier non signé est parfaitement définie par la norme du C dans tous les cas :
    Le résultat est égal à la valeur de l'entier ramenée dans la plage de valeurs de l'entier non signé par ajout ou soustraction d'un nombre de fois suffisant de la valeur maximum de l'entier non signé +1.

    J'explicite sur un exemple : Soit à convertir un int vers un unsigned char de valeur maximum 255.
    - soit un int valant 25762
    Comme 25762 = 100*256+162, l'unsigned char vaudra 162 (= 25762-100*256 donc par 100 soustractions de 256).
    - soit un int valant -25762
    Comme -25762 = -101*256+94, l'unsigned char vaudra 94 (= -25762+101*256 donc par 101 additions de 256).
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    int i = 25762;
    unsigned char uci = i; // uci==162
    int j = -25762;
    unsigned char ucj = j; // ucj==94
    Le return -1 dans ton code retourne donc en fait 4 294 967 295

    La conversion d'un entier vers un entier signé est plus problématique : si la valeur du nombre peut être représentée dans la plage de valeur de l'entier signé, alors la conversion conserve la valeur. Sinon le résultat dépend de l'implémentation (et n'est donc pas portable)
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    unsigned int ui = 122;
    signed char scui = ui ;  // scui==122
    unsigned int uj = 254;
    signed char scuj = uj ;  // scuj==??? dépend de l'implémentation pour un signed char <=127
    Tu peux donc avoir des problèmes si ton code se poursuit par quelque chose du genre :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    long int i = dec_to_binary(....)
    // ou 
    if(dec_to_binary(....)==-1)...
    // et le compilateur devrait émettre un warning pour la comparaison signé/non signé
    dont le résultat est dépendant de l'implémentation.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. graphe :pourquoi la valeur de l'axe y est vide
    Par nb-wissam dans le forum Reports
    Réponses: 0
    Dernier message: 18/09/2010, 15h07
  2. Réponses: 6
    Dernier message: 06/09/2009, 14h03
  3. Réponses: 3
    Dernier message: 04/03/2007, 09h34
  4. Mon site n'est toujours pas référencé : que faire ?
    Par Thanor dans le forum Référencement
    Réponses: 12
    Dernier message: 15/10/2006, 15h28
  5. Réponses: 14
    Dernier message: 04/10/2006, 00h19

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo