[C++] Problème avec des unions de structures
Répondre à la discussion
Affichage des résultats 1 à 14 sur 14

[C++] Problème avec des unions de structures



  1. #1
    Jack
    Modérateur

    [C++] Problème avec des unions de structures


    ------

    Bonjour,

    une fois n'est pas coutume, c'est à moi de poser une question. Les déclarations suivantes génèrent une erreur:
    Code:
    struct serialConfig{
        QString portName;
        int baud;
        int charSize;
        char parity; // n, e, o
    }; 
    
    struct ethernetConfig{   
       QString ip;    
       QString mask;   
       int port;
    }; 
    
    union config{
        serialConfig sConfig;
        ethernetConfig eConfig; 
    };
    Code:
    1>main.cpp(23): error C2621: 'config::sConfig' : membre d'union illégal ; le type 'serialConfig' a un constructeur de copie
    1>main.cpp(24): error C2621: 'config::eConfig' : membre d'union illégal ; le type 'ethernetConfig' a un constructeur de copie
    J'ai contourné le problème en utilisant une union anonyme, mais j'aimerais bien savoir la cause de l'erreur. J'ai bien conscience que struct et class sont équivalents dans le cas présent, mais pourquoi ai-je ce problème de constructeur de copie? La doc de msdn est peu loquace pour cette erreur C2621.

    Merci pour vos lumières

    -----

  2. #2
    pm42

    Re : [C++] Problème avec des unions de structures

    Tu as pas mal de réponses sur stackoverflow : en gros, si un des éléments de l'union a besoin d'un constructeur, d'un copy-constructor ou d'un destructeur non trivial, alors ce n'est pas autorisé.
    En gros, comment copier une union, l'affecter à une autre si tu as autre chose que des champs qui se copient bit à bit ?

    http://stackoverflow.com/questions/7...py-constructor

    Dans ton cas, je parierais sur QString.

  3. #3
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    Ok.

    Il n'y a pas moyen en C++ de déclarer des structures simples comme en C, sans méthodes, constructeurs etc.?

  4. #4
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    J'ai bien noté cette phrase:
    An object of a class with a non-trivial constructor, a non-trivial copy constructor, a non-trivial destructor, or a non-trivial copy assignment operator cannot be a member of a union
    Et pourtant avec une union anonyme, ça passe avec mes QString qui sont une implémentation des chaines dans la librairie Qt, donc similaires aux std:: string
    Code:
    union configuration{
    	struct {
    		QString portName;
    		int baud;
    		int charSize;
    		char parity; // n, e, o
    	} ;
    
    	struct {
    		QString ip;
    		QString mask;
    		int port;
    	};
    };
    Dernière modification par Jack ; 08/02/2016 à 14h56.

  5. A voir en vidéo sur Futura
  6. #5
    Chanur

    Re : [C++] Problème avec des unions de structures

    Citation Envoyé par Jack Voir le message
    Ok.

    Il n'y a pas moyen en C++ de déclarer des structures simples comme en C, sans méthodes, constructeurs etc.?
    Si j'ai bien compris (je ne suis pas expert en C++), non : en C++ "struct" désigne simplement une classe dont les membres sont publics par défaut au lieu d'être privés.

    Néanmoins, on a le droit d'interpréter les octets d'un objet comme s'il s'agissait d'un objet différent : c'est ce que fait reinterpret_cast ...

    Sinon, j'ai compilé ton code et obtenu les mêmes erreurs, mais gcc me dit aussi :
    "unrestricted unions only available with -std=c++0x or -std=gnu++0x"

    J'ai essayé avec chacune des options et ça se compile sans erreur. Je n'ai pas testé (flemme d'écrire le bout de code nécessaire ... ).

    man dit pour ces options :
    c++0x
    The working draft of the upcoming ISO C++0x standard. This option enables experimental features that are likely to be included in C++0x. The working draft is constantly changing, and any feature that is enabled by this flag may be removed from future versions of GCC if it is not part of the C++0x standard.

    gnu++0x
    GNU dialect of -std=c++0x. This option enables experimental features that may be removed in future versions of GCC.

    Ça a l'air instable ...
    Dernière modification par Chanur ; 08/02/2016 à 23h50.
    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  7. #6
    pm42

    Re : [C++] Problème avec des unions de structures

    Citation Envoyé par Jack Voir le message
    J'ai bien noté cette phrase:
    Et pourtant avec une union anonyme, ça passe avec mes QString qui sont une implémentation des chaines dans la librairie Qt, donc similaires aux std:: string
    Je connais Qt et effectivement, dans ce cas, QSring, std::string ou toute classe avec un constructeur/destructeur, c'est kif kif.
    Tu utilises quoi comme compilo pour que ça passe ? Parce que j'ai le même messsage avec cette version du code : anonymous struct member 'mask' has a non-trivial copy constructor

  8. #7
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    J'utilise Visual studio 2013 pour mes tests. A terme, l'appli devra tourner sur une raspberry pi, et donc être compilée avec gcc.

    Comme il faut que j'aie terminé mon programme dans une dizaine de jours, je passe "en force" tant que ça fonctionne, Je vais encapsuler tout ça dans une classe, quitte à modifier plus tard dans les règles quand j'aurai plus de temps.

  9. #8
    Paraboloide_Hyperbolique

    Re : [C++] Problème avec des unions de structures

    Bonjour Jack,

    Voici ce que je pense du problème (je ne suis pas spécialiste, donc je peux me tromper):

    Je t'apprend rien en disant qu'une union d'objets {A_i} attribue le même espace mémoire pour ces différents objets (de taille max_i {A_i}).

    Ton code:

    Code:
    union config{
        serialConfig sConfig;
        ethernetConfig eConfig; 
    };
    Déclare explicitement deux objets sConfig et eConfig. Lorsque un objet de type "config" est construit, puisque les objets sConfig et eConfig occupent le même espace mémoire le compilateur ne sait pas s'il doit construire sConfig ou eConfig (même chose lors de la destruction).

    Par contre dans:

    Code:
    union configuration{
    	struct {
    		QString portName;
    		int baud;
    		int charSize;
    		char parity; // n, e, o
    	} ;
    
    	struct {
    		QString ip;
    		QString mask;
    		int port;
    	};
    };
    Aucun objet n'est déclaré, que des types (anonymes). Aucun appel à un constructeur/destructeur des types (anonymes) n'est requis lors de la construction d'un objet "configuration". Le compilateur n'a donc pas de choix ambigu à faire.

  10. #9
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    Lorsque un objet de type "config" est construit, puisque les objets sConfig et eConfig occupent le même espace mémoire le compilateur ne sait pas s'il doit construire sConfig ou eConfig (même chose lors de la destruction).


    Hé oui, c'est évident une fois qu'on a l'explication ...

  11. #10
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    Bon, j'ai maintenant un problème pour retourner mon union depuis une fonction. Voici un petit programme qui met en évidence le problème et qui crashe lorsque la fonction f retourne u.
    Exception de première chance à 0x0f94797f (msvcp90d.dll) dans bidon.exe : 0xC0000005: Violation d'accès lors de l'écriture à l'emplacement 0x00000001.Exception non gérée à 0x0f94797f (msvcp90d.dll) dans bidon.exe : 0xC0000005: Violation d'accès lors de l'écriture à l'emplacement 0x00000001.

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include <string>
    
    
    using namespace std;
    
    
    union uni
    {
    	struct
    	{
    		int v1;
    		string v2;
    	};
    	struct
    	{	
    		string v3;
    		char v4;
    		int v5;
    	};
    };
    
    
    uni f()
    {
    	uni u;
    	u.v1 = 1;
    	u.v2 = "Hello";
    	return u;
    }
    
    
    
    
    int main ()
    {
    	uni u=f();
    	return 0;
    }
    Pourtant la taille de l'union est connue du compilateur et le résultat est passé par la pile. Le fait que l'union contienne des string ne doit pas modifier sa taille car la chaine elle même doit se trouver dans le tas.
    C'est surement évident à nouveau, mais je ne vois pas.

  12. #11
    Chanur

    Post Re : [C++] Problème avec des unions de structures

    gcc ne veut pas compiler ton code :
    Code:
    gcc -o union union.cpp
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with constructor not allowed in anonymous aggregate
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with destructor not allowed in anonymous aggregate
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with copy assignment operator not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with constructor not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with destructor not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with copy assignment operator not allowed in anonymous aggregate
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with constructor not allowed in union
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with destructor not allowed in union
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with copy assignment operator not allowed in union
    union.cpp:14:10: note: unrestricted unions only available with -std=c++0x or -std=gnu++0x
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with constructor not allowed in union
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with destructor not allowed in union
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with copy assignment operator not allowed in union
    Si j'ajoute l'option -std=c++0x, ça ne marche pas non plus, mais j'ai des messages peut-être plus explicites :
    Code:
    gcc -std=c++0x -o union union.cpp
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with constructor not allowed in anonymous aggregate
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with destructor not allowed in anonymous aggregate
    union.cpp:14:10: erreur: member ‘std::string uni::<anonymous struct>::v2’ with copy assignment operator not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with constructor not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with destructor not allowed in anonymous aggregate
    union.cpp:18:10: erreur: member ‘std::string uni::<anonymous struct>::v3’ with copy assignment operator not allowed in anonymous aggregate
    union.cpp: In constructor ‘uni::uni(uni&&)’:
    union.cpp:9:7: erreur: initializations for multiple members of ‘uni’
    union.cpp:12:2: erreur: ‘uni::<anonymous struct>::~._83()’ is inaccessible
    union.cpp:9:7: erreur: à l'intérieur du contexte
    union.cpp:17:2: erreur: ‘uni::<anonymous struct>::~._84()’ is inaccessible
    union.cpp:9:7: erreur: à l'intérieur du contexte
    union.cpp: In function ‘uni f()’:
    union.cpp:30:9: note: synthesized method ‘uni::uni(uni&&)’ first required here
    Il semble que pour initialiser les structures anonymes de ton union, il veuille les destructeurs. Ce qui est évidemment absurde : même s'ils existaient, ça n'aurait aucun sens d'utiliser les deux.

    Ce qui se conçoit bien s'énonce clairement ; et les mots pour le dire arrivent aisément.

  13. #12
    Paraboloide_Hyperbolique

    Re : [C++] Problème avec des unions de structures

    J'ai la même chose avec g++ (Ubuntu 4.8.4-2ubuntu1~14.04) 4.8.4.

    Il y a moyen de s'en tirer avec:

    Code:
    union uni
    {
    	struct
    	{
    		int v1;
    		string* v2;
    	};
    	struct
    	{	
    		string* v3;
    		char v4;
    		int v5;
    	};
    };
    (Placer des pointeurs devant les string).

    Cela évite de faire appel au constructeur/destructeur de string lors de la construction d'un 'uni'. Par contre, il faut alors explicitement gérer la mémoire sur le tas pour les variables v2 et v3.

  14. #13
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    Bon, j'ai eu des indications par ailleurs et mon code est effectivement un peu foireux car les caractères de la chaine ne sont pas copiés lors du retour du résultat de la fonction. Il y a donc bien un problème de constructeur de copie.

    J'ai modifié mon code pour passer cette fois une référence:
    Code:
    void f(uni& u){
        u.v1 = 1;
        u.v2 = "Hello";
    }
    
    int main ()
    {
        uni u;
        f(u);
        return 0;
    }
    Ca fonctionne, mais on me dit que ça ne devrait pas. Pourtant le résultat est correct.

  15. #14
    Jack
    Modérateur

    Re : [C++] Problème avec des unions de structures

    Citation Envoyé par Paraboloide_Hyperbolique Voir le message
    (Placer des pointeurs devant les string).

    Cela évite de faire appel au constructeur/destructeur de string lors de la construction d'un 'uni'. Par contre, il faut alors explicitement gérer la mémoire sur le tas pour les variables v2 et v3.
    Il faut que j'avance absolument. Je vais remplacer les string par des Cstring pour ne plus avoir d'allocation dynamique à gérer.

Discussions similaires

  1. problème de dimensionnement des structures
    Par invite3b0d1102 dans le forum Physique
    Réponses: 3
    Dernier message: 03/12/2015, 11h28
  2. Mécanique des structures / structures en nid d'abeille
    Par invited4743cb4 dans le forum TPE / TIPE et autres travaux
    Réponses: 3
    Dernier message: 12/10/2015, 07h12
  3. Réponses: 6
    Dernier message: 30/10/2011, 22h07
  4. [2nde] Inéquations solution unions
    Par inviteb4ebd1a1 dans le forum Mathématiques du collège et du lycée
    Réponses: 1
    Dernier message: 11/01/2009, 16h09
  5. C : Initialisation de structures/tableaux de structures
    Par invitef1d0ad93 dans le forum Logiciel - Software - Open Source
    Réponses: 1
    Dernier message: 12/08/2008, 10h57