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 :

Etat initial déclaration


Sujet :

C++

  1. #21
    Membre éprouvé
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    189
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Par défaut
    J'ai un souvenir de Koenig, Moo ou Stroustrup qui disait que les variables étaient initialisé par défaut à 0. P-ê est-ce le compilo' qui n'est pas bon ?

    En tout cas ce n'est pas le cas avec MinGW. :
    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
    struct maStruct{
        int size;
        char t_array;
        unsigned char t_array2;
    };
    void testStructInit(void)
    {
        int tot(0);
        for (int k(0); k < 1000; ++k) {
            maStruct m_tbl[1000];
            for (int i(0); i < 1000; ++i) {
                if ( m_tbl[i].size != 0 || m_tbl[1].t_array != 0 || m_tbl[i].t_array2 != 0) {
                    // std::cout << "i : " << i << "\n";
                    ++tot;
                }
            }
     
            //std::cout << "tot : " << tot << std::endl;
        }
        std::cout << tot/1000.f/1000.f*100.f << "% non 0 initialised." << std::endl;
    }
    Avec à peu près 60%. Toujours la même proportion ( sans redémarrage ) .

  2. #22
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Goten Voir le message
    5 To default-initialize an object of type T means:
    — if T is a non-POD class type (clause 9), the default constructor for T is called (and the initialization is ill-formed
    if T has no accessible default constructor);
    — if T is an array type, each element is default-initialized;
    — otherwise, the object is zero-initialized.
    Donc les variables sont bien zero initialized dans le cas d'une structure sans constructeur et donc on applique ça :
    Si je comprends bien ce passage, il explique comment est réalisée l'initialisation par défaut, pas quand.
    En particulier rien ne dit qu'un objet non static et sans initialiseur doit subir la "default-initialize".

    Par contre ceci :

    9 If no initializer is specified for an object, and the object is of (possibly cv-qualified) non-POD class type (or array thereof), the object shall be default-initialized; if the object is of const-qualified type, the underlying
    class type shall have a user-declared default constructor. Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value; if the object or any
    of its subobjects are of const-qualified type, the program is ill-formed.
    dit bien que dans le cas de figure évoqué il n'y a pas d'initialisation par défaut de faite.

  3. #23
    Membre Expert

    Inscrit en
    Mai 2008
    Messages
    1 014
    Détails du profil
    Informations forums :
    Inscription : Mai 2008
    Messages : 1 014
    Par défaut
    Ben alors !?

    Vous n'avez jamais perdu deux jours à debugger un programme qui crash mystérieusement parce qu'un put%!*$ de programmeur à oublier de coder un constructeur par défaut à sa structure S{truc* p;}, qui initialiserait le pointeur membre p à NULL, ce qui fait que le test "if(p)" renvoie true, donc le programme s'engage dans la mauvaise branche un peu trop tôt, appelle tout un tas d'autres fonctions et tout se termine lamentablement en race condition deux threads plus loin !?

    Il faut toujours initialiser les variables d'une structure, classe, tableau ou quoi que soit en C++ ! Ça doit être un réflex pavlovien :

    Ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    struct S
    {
      int i;
      unsigned char* c;
    };
    est MAL


    Ce code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    struct S
    {
      S():i(0),c(NULL){}
      int i;
      unsigned char* c;
    };
    est BIEN

    Bon d'accord, il existe une exception concernant les variables statiques, mais les règles sont trop subtiles et compliquées à retenir à mon gout, je préfère me souvenir de : une déclaration = une initialisation

  4. #24
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    @gl : en effet j'ai pris default-initializer au premier sens, ie j'avais compris que c'était le comportement par défaut quand rien n'est précisé, mais non.
    Avec
    Otherwise, if no initializer is specified for a non-static object, the object and its subobjects, if any, have an indeterminate initial value;
    Tout est plus clair et surtout plus sensé. Car en effet je repensais au bête exemple (cité par arzar) qui fait bugué un calcul pour une variable non initialisé.

    Bon la conclusion que j'en tirerais : cisco est brain-damage

    edit : tu pourrais préciser le paragraphe cité gl?

  5. #25
    Membre confirmé
    Profil pro
    Inscrit en
    Novembre 2003
    Messages
    113
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2003
    Messages : 113
    Par défaut
    Oui je suis bien dans ce cas la ou je test un pointeur comme etant NULL :/

    Par contre dans mon cas, le programme va tourner sur plusieurs serveurs à 16 coeurs l'un... Dans ce cas la, la moindre optimisation prend tout son sens et fait economiser pas mal d'euros.

    Alors d'un côté il ya le risque de crash dur à debugger mais de l'autre si je peux eviter d'initialiser des millions d'objets par secondes qui sont deja initialisés à la base, je pense que ca serait pas un mal :s

  6. #26
    Membre éprouvé
    Étudiant
    Inscrit en
    Octobre 2007
    Messages
    189
    Détails du profil
    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Octobre 2007
    Messages : 189
    Par défaut
    Citation Envoyé par seal3 Voir le message
    Alors d'un côté il ya le risque de crash dur à debugger mais de l'autre si je peux eviter d'initialiser des millions d'objets par secondes qui sont deja initialisés à la base, je pense que ca serait pas un mal :s
    J'aurais tendance à dire que le compilo se charge de ce genre d'optimisation ( -> avec la liste d'initialisation tu ne perds pas de temps ) . Est-ce que la norme précise qqch la dessus ?

  7. #27
    Membre Expert
    Avatar de Goten
    Profil pro
    Inscrit en
    Juillet 2008
    Messages
    1 580
    Détails du profil
    Informations personnelles :
    Âge : 35
    Localisation : France

    Informations forums :
    Inscription : Juillet 2008
    Messages : 1 580
    Par défaut
    Sur? Ce qu'est sur c'est qu'il faut pas laissez tes variables dans un état inconnue 'juste' pour des considérations de performances.

  8. #28
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Sur? Ce qu'est sur c'est qu'il faut pas laissez tes variables dans un état inconnue 'juste' pour des considérations de performances.
    Du moins, pas avant d'avoir mesuré et établi clairement que c'était ça qui te faisait perdre du temps.

  9. #29
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Et tu as même des variantes amusantes !!!

    Sous Visual, en Release, une variable locale est initialisée à zéro. En Debug, elle est remplie par des octets 0xCC : mauvaise pioche si on présuppose qu'elles sont "nulles" par défaut...

    On a alors un programme qui crashe en Debug et qui fonctionne en Release, toujours un vrai bonheur à débugger, ça.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  10. #30
    gl
    gl est déconnecté
    Rédacteur

    Homme Profil pro
    Inscrit en
    Juin 2002
    Messages
    2 165
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 46
    Localisation : France, Isère (Rhône Alpes)

    Informations forums :
    Inscription : Juin 2002
    Messages : 2 165
    Par défaut
    Citation Envoyé par Goten Voir le message
    edit : tu pourrais préciser le paragraphe cité gl?
    Dans la version du document que j'ai, c'est le point 9 du paragraphe d'où tu as tiré ton extrait.

    Citation Envoyé par Mac LAK Voir le message
    Sous Visual, en Release, une variable locale est initialisée à zéro. En Debug, elle est remplie par des octets 0xCC : mauvaise pioche si on présuppose qu'elles sont "nulles" par défaut...
    L'initialisation en mode debug des variables non initialisée à une valeur spécifique et non nulle est une fonctionnalité que j'ai toujours apprécié dans Visual.
    En effet :
    • Puisque c'est en debug, la perte de temps éventuellement induite n'a aucune importance.
    • Cela permet très vite de détecter des erreurs sur des variables non initialisées (particulièrement agréable lors de la reprise d'un code existant).
    • C'est une aide assez sympa pour débuger les débordements de buffer.

  11. #31
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Sous Visual, en Release, une variable locale est initialisée à zéro.
    C'est sûr ce truc ?
    J'émet un doute. Pour l'avoir souvent vécu, en release, une variable locale est non initialisée (je ne parle pas des classes, je parle des variables genre int et autres)
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  12. #32
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Ça dépend des options de compilation (donc, des options du projet).

    Dans tous les cas, ça me semble très mal de faire du code qui se base là-dessus. Soit l'initialisation fait partie de l'algorithme (ie, l'algorithme a besoin que la variable soit initialisée à 0), auquel cas, il faut l'expliciter dans le code, soit elle n'en fait pas partie, et il n'y a pas besoin de la faire, et il faut mettre un petit commentaire précisant qu'on n'initialise pas *exprès* et que ce n'est pas un oubli.

  13. #33
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par ram-0000 Voir le message
    C'est sûr ce truc ?
    J'émet un doute. Pour l'avoir souvent vécu, en release, une variable locale est non initialisée (je ne parle pas des classes, je parle des variables genre int et autres)
    Cela ne concerne QUE les variables locales (et les globales, mais ce n'est pas le même mécanisme). Cela ne touche pas les variables allouées, ce qui met le plus souvent les objets dans le lot.

    Je crois qu'en optimisation maximale, cette fonction saute, je t'avoue que je n'ai jamais poussé très loin cette recherche. En tout cas, c'est certain que c'est le cas avec un mode Release "gentil", c'est à dire pas trop optimisé, et il me semble bien que le réglage par défaut Release implique un vidage à zéro des locales. Ça n'existe par contre jamais ni en Debug, ni en Release optimisé à mort.

    Dans tous les cas, je pense qu'on est tous d'accord : se baser sur une initialisation "automatique", qu'elle soit au chargement de l'EXE (globales) ou induite par le compilateur (locales, dynamiques), c'est franchement super crade et c'est une source de bugs parfois pénible à retrouver.
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  14. #34
    Rédacteur

    Avatar de ram-0000
    Homme Profil pro
    Consultant en sécurité
    Inscrit en
    Mai 2007
    Messages
    11 517
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 62
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations professionnelles :
    Activité : Consultant en sécurité
    Secteur : High Tech - Opérateur de télécommunications

    Informations forums :
    Inscription : Mai 2007
    Messages : 11 517
    Par défaut
    Persiste et signe :

    Avec Visual Studio 2005
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    #ifndef _WIN32_WINNT   
    #define _WIN32_WINNT 0x0501
    #endif						
     
    #include <stdio.h>
    #include <tchar.h>
     
     
    int _tmain(int argc, _TCHAR* argv[])
    {
    	int toto;
    	printf("Toto=%d\n", toto);
    	return 0;
    }
    Warning à la compilation :
    console.cpp(15) : warning C4700: variable locale 'toto' non initialisée utilisée
    Exécution de la version release (avec les options par défaut d'un projet console standard)
    release>Console.exe
    Toto=2015115244
    La variable toto n'est pas initialisée
    Raymond
    Vous souhaitez participer à la rubrique Réseaux ? Contactez-moi

    Cafuro Cafuro est un outil SNMP dont le but est d'aider les administrateurs système et réseau à configurer leurs équipements SNMP réseau.
    e-verbe Un logiciel de conjugaison des verbes de la langue française.

    Ma page personnelle sur DVP
    .

  15. #35
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Étrange, je suis pourtant sûr et certain de cette initialisation à zéro, j'ai eu la farce avec un projet justement qui crashait en Debug et fonctionnait en Release.
    Et je ne crois pas aux coïncidences qui feraient qu'un programme tombe "par hasard" sur un zéro en mémoire non-initialisée à chaque exécution, quelle que soit la machine qui le lance...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  16. #36
    Membre Expert
    Avatar de white_tentacle
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    1 505
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2008
    Messages : 1 505
    Par défaut
    Comme dit :
    Ça dépend des options de compilation (donc, des options du projet).
    Indépendant de debug/release, donc, c'est bien une option à part.

    Mais je crois vraiment que par défaut, sous visual, c'est zéro-initialisation en debug (ie, la configuration générée pour le mode debug inclut cette option) et pas d'initialisation en release (ce qui est à mon avis une erreur, mieux vaudrait ne jamais initialiser à zéro).

  17. #37
    Expert confirmé

    Inscrit en
    Novembre 2005
    Messages
    5 145
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 5 145
    Par défaut
    Citation Envoyé par Mac LAK Voir le message
    Étrange, je suis pourtant sûr et certain de cette initialisation à zéro, j'ai eu la farce avec un projet justement qui crashait en Debug et fonctionnait en Release.
    Et je ne crois pas aux coïncidences qui feraient qu'un programme tombe "par hasard" sur un zéro en mémoire non-initialisée à chaque exécution, quelle que soit la machine qui le lance...
    J'ai déjà vu un programme fonctionner comme ça. Deux appels à des fonctions différentes se suivaient; la première fonction initialisait correctement les variables locales pour la seconde. Ça fonctionnait plus en changeant d'architecture; un optimiseur jouant différemment avec les registres aurait aussi causé des problèmes.

  18. #38
    Inactif  
    Avatar de Mac LAK
    Profil pro
    Inscrit en
    Octobre 2004
    Messages
    3 893
    Détails du profil
    Informations personnelles :
    Âge : 51
    Localisation : France, Haute Garonne (Midi Pyrénées)

    Informations forums :
    Inscription : Octobre 2004
    Messages : 3 893
    Par défaut
    Citation Envoyé par Jean-Marc.Bourguet Voir le message
    J'ai déjà vu un programme fonctionner comme ça. Deux appels à des fonctions différentes se suivaient; la première fonction initialisait correctement les variables locales pour la seconde. Ça fonctionnait plus en changeant d'architecture; un optimiseur jouant différemment avec les registres aurait aussi causé des problèmes.
    OK, mais là, c'était sur des dizaines et dizaines de variables, toutes étaient à zéro quoi qu'il arrive... Problème similaire sur un programme annexe, là aussi : tout à zéro en Release, valeurs 0xCC en Debug => problème constant et récurrent.

    Pour ça que je dis "étrange"...
    Mac LAK.
    ___________________________________________________
    Ne prenez pas la vie trop au sérieux, de toutes façons, vous n'en sortirez pas vivant.

    Sources et composants Delphi sur mon site, L'antre du Lak.
    Pas de question technique par MP : posez-la dans un nouveau sujet, sur le forum adéquat.

    Rejoignez-nous sur : Serveur de fichiers [NAS] Le Tableau de bord projets Le groupe de travail ICMO

  19. #39
    Expert éminent
    Avatar de koala01
    Homme Profil pro
    aucun
    Inscrit en
    Octobre 2004
    Messages
    11 644
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 53
    Localisation : Belgique

    Informations professionnelles :
    Activité : aucun

    Informations forums :
    Inscription : Octobre 2004
    Messages : 11 644
    Par défaut
    Salut,

    Le problème vient peut être aussi, tout bêtement, de la version du compilateur que vous utilisez...

    En effet, vous êtes là à vous chamailler sur le comportement propre au compilateur (mais non standard) sans même avoir pensé à vérifier que vous étiez bien occupés à comparer ce qui est comparable, donc, par défaut, que vous utilisiez bel et bien la même version du compilateur

    C'est le plus embêtant quand on se base sur une expérience personnelle pour essayer de déduire le comportement du compilo: trois situations peuvent se présenter:
    • Le compilateur suit scrupuleusement la norme, et, dans ce cas, l'exemple que vous donnez devrait être reproductible sur n'importe quel autre compilateur qui la respecte sur ce point particulier.
    • Le compilateur ne suit pas scrupuleusement la norme, mais a gardé un comportement similaire au fil des différentes versions (et il ne faut quand même pas oublier que VC++ sort en moyenne tous les deux ans, et que la philosophie de microsoft vis à vis des normes a fortement évolué depuis 2005...)
    • Le compilateur ne suis pas scrupuleusement la norme sur un point précis, et ses concepteurs ont décidé de modifier le comportement, soit pour faire en sorte que la version suivante suive la norme, soit, simplement, parce qu'ils ont considéré qu'une valeur particulière (dans le cas qui nous occupe ici) était sommes toutes plus "cohérente" qu'une autre.

    D'ailleurs, je ne serais même pas surpris si, en lisant la liste des changements par rapport à la version précédente de VC++, vous trouviez justement un passage concernant l'initialisation par défaut des variables (mais bon, qui prend régulièrement la peine d'étudier un tout petit peu attentivement les changements apporté )
    A méditer: La solution la plus simple est toujours la moins compliquée
    Ce qui se conçoit bien s'énonce clairement, et les mots pour le dire vous viennent aisément. Nicolas Boileau
    Compiler Gcc sous windows avec MinGW
    Coder efficacement en C++ : dans les bacs le 17 février 2014
    mon tout nouveau blog

Discussions similaires

  1. [WD18] Etat initial d'un bouton dans un ruban
    Par jacquesprogram dans le forum WinDev
    Réponses: 2
    Dernier message: 12/09/2013, 17h24
  2. Etat initial mutex
    Par thierryG dans le forum Windows
    Réponses: 3
    Dernier message: 18/10/2007, 21h31
  3. Réponses: 4
    Dernier message: 12/03/2006, 20h47
  4. Réponses: 8
    Dernier message: 06/03/2006, 14h44
  5. Réponses: 8
    Dernier message: 17/05/2002, 09h08

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