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

Langage C++ Discussion :

C++ Cast void * / struct


Sujet :

Langage C++

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Par défaut C++ Cast void * / struct
    j'essaye de mettre en place en C++ (std= c98 ) un typedef a base de structure pour prendre en compte un retour d'erreur et une autre structure de resultat defini comme suit
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct s_res
    {
    	bool	ks;
    	void	*res;
    }	t_res;
    void * devant contenir le pointeur de la structure

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    typedef struct s_chk_idx
    {
    	bool		ks;
    	size_t	idx;
    }	t_chk_idx;
    puis lors de l'utilisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    t_res PhoneBook::getCmd(void)
    {
    	t_chk_idx		chk;
    	t_res			kr;
     
      ...do somethink
    	kr.res = (void *)(&chk);
    	return kr;
    }
    et dans le code l'appellant

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    int main(void)
    {
           ...
    	s_res	ret;
    	t_chk_idx chk;
     
          ....
    	ret = Book.getCmd();
    	chk =(t_chk_idx)(ret.res);
          ...
    }
    le compilateur renvoie une erreur

    error: no matching conversion for C-style cast from 'void *' to 't_chk_idx' (aka 's_chk_idx')
    chk =(t_chk_idx)(ret.res);

    base.hpp:41:16: note: candidate constructor (the implicit copy constructor) not viable: cannot convert argument of incomplete type 'void *' to 'const s_chk_idx' for 1st argument
    typedef struct s_chk_idx

    j'ai egalement le meme prb en C ( error: conversion to non-scalar type requested) , est-ce qu'un cast void * vers pointeur de structure est possible ?

  2. #2
    CGi
    CGi est déconnecté
    Expert confirmé
    Avatar de CGi
    Profil pro
    Inscrit en
    Mars 2002
    Messages
    1 061
    Détails du profil
    Informations personnelles :
    Localisation : France, Allier (Auvergne)

    Informations forums :
    Inscription : Mars 2002
    Messages : 1 061
    Par défaut
    Peut-être plutôt :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chk = *(t_chk_idx*)ret.res;
    Et comme on est en C++ :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    chk = *static_cast<t_chk_idx*>(ret.res);
    Site : http://chgi.developpez.com

    Pourquoi faire simple quand on peut faire compliqué ? (Jacques Rouxel)

  3. #3
    Expert confirmé
    Homme Profil pro
    Analyste/ Programmeur
    Inscrit en
    Juillet 2013
    Messages
    4 748
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Analyste/ Programmeur

    Informations forums :
    Inscription : Juillet 2013
    Messages : 4 748
    Par défaut
    En réalité, le compilateur te dit le pourquoi de l'erreur

    Déjà, tu es 1 fou des pointeurs de fonction, du void* … donc du bon C des familles
    Et les experts ici te diront que le C++98 est dépassé depuis 25 ans, et le C++ moderne (C++11, C++14, C++17, …) a déjà + de 10 ans.

    Déjà grosse erreur : tu prends le pointeur d'1 variable locale.
    Les variables locales sont détruites à la fin du "bloc", donc les variables kr et chk seront détruites à la fin de l'appel de la fonction PhoneBook::getCmd.

    https://www.onlinegdb.com/ me dit
    error: no matching function for call to ‘s_chk_idx::s_chk_idx(void*&)’
    Le problème est l'affectation chk =(t_chk_idx)(ret.res); : le compilateur ne sait pas convertir 1 void* en t_chk_idx et il te demande de faire 1 constructeur de copie.

    Donc, il faut faire 1 constructeur de copie dans ta structure struct s_chk_idx/ t_chk_idx.

    bizarre, tu n'as pas utilisé ta variable entre la définition et cette affectation.

    1 truc mal codé : la fonction PhoneBook::getCmd ne retourne ni 1 pointeur ni 1 référence (&)
    Donc au retour ret = Book.getCmd();, l'affectation va appeler soit le constructeur de copie soit l'opérateur d'affectation.


    La différence entre le C et le C++, en C++, 1 structure est 1 classe avec 1 encapsulation publique par défaut (privé pour les classes). En C, tu ne peux pas mettre dans 1 structure des fonctions et des constructeurs (mais des pointeurs de fonction )
    1 autre différence, en C, tu n'as pas besoin de caster void* (par exemple la fonction malloc).

  4. #4
    Membre averti
    Profil pro
    Inscrit en
    Mars 2010
    Messages
    57
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2010
    Messages : 57
    Par défaut
    Je sais que le langage est dépassé mais pas le choix de celui ci c'est un langage imposé dans le cursus de formation , trouver de la doc d'une vieillerie pareille est plus difficile que trouver celle du C ...
    après ce langage c'est l'apprentissage du Rust .

    je n'ai pas utilisé des variables autre que locale pour gérer des flag de sortie d'erreur et de retour d'une fonction qui me sert de contrôle de flux (aiguillage) dans la fonction appelante.
    effectivement l'autre alternative aurait été de faire un passage par référence de la structure et renvoyer un booléen d'erreur

    la solution du cast proposé par CGI fonctionne , merci

  5. #5
    Expert confirmé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Février 2005
    Messages
    5 435
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Conseil

    Informations forums :
    Inscription : Février 2005
    Messages : 5 435
    Par défaut
    effectivement l'autre alternative aurait été de faire un passage par référence de la structure et renvoyer un booléen d'erreur
    Les exceptions (lancement), ça existe aussi en C++.

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

Discussions similaires

  1. Cast void* - Objet C++
    Par LaMainSurLeKatana dans le forum C++
    Réponses: 5
    Dernier message: 24/08/2010, 13h09
  2. cast (void*) -> (char)
    Par nicodn02 dans le forum C
    Réponses: 10
    Dernier message: 14/04/2008, 10h02
  3. cast sur un void*
    Par rikau2 dans le forum C++
    Réponses: 5
    Dernier message: 17/08/2007, 14h05
  4. cast conditionel d'un void *
    Par apesle dans le forum C
    Réponses: 4
    Dernier message: 09/02/2007, 08h41
  5. Surdéfinition de l'opérateur de cast (void *)
    Par Thierry Chappuis dans le forum C++
    Réponses: 4
    Dernier message: 07/12/2006, 11h21

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