web-dev-qa-db-fra.com

Valeur par défaut d'un booléen non défini en C ++?

Duplicata possible:
Pourquoi une variable booléenne C++ est-elle vraie par défaut?

Dis que je devais faire quelque chose comme ça:

class blah
{
  public:
  bool exampleVar;
};

blah exampleArray[4];
exampleArray[1].exampleVar = true;

Dans exampleArray, il existe maintenant 3 instances non définies d'exempleVar, quelles sont leurs valeurs par défaut sans que je les définisse?

19
Lemmons

La valeur par défaut dépend de l'étendue dans laquelle exampleArray est déclarée. Si elle est locale à une fonction, les valeurs seront aléatoires, quelles que soient les valeurs de ces emplacements de pile. S'il est statique ou déclaré à la portée du fichier (global), les valeurs seront initialisées à zéro.

Voici une démonstration. Si vous avez besoin d'une variable membre pour avoir une valeur déterministe, initialisez-la toujours dans le constructeur.

class blah
{
  public:
  blah() 
  : exampleVar(false)
  {}

  bool exampleVar;
};

MODIFIER:
Le constructeur dans l'exemple ci-dessus n'est plus nécessaire avec C++ 11. Les membres de données peuvent être initialisés dans la déclaration de classe elle-même.

class blah
{
  public:
  bool exampleVar = false;
};

Cette valeur par défaut en ligne peut être remplacée par un constructeur défini par l'utilisateur si vous le souhaitez.

45
Praetorian
struct x
{
    bool b;

    x() : b() { }
}

...
x myx;

dans ce cas, myx.b sera faux.

struct x
{
    bool b;
}

...
x myx;

dans ce cas, myx.b sera imprévisible, ce sera la valeur que l'emplacement de la mémoire avait avant d'allouer myx.

Comme en C et C++, une fausse valeur est définie comme 0 et une vraie valeur est définie comme non nulle, il y a une plus grande possibilité qu'un emplacement d'adresse aléatoire contienne une vraie valeur au lieu d'une fausse valeur. Habituellement, en C++, sizeof (bool) est 1, c'est-à-dire 8 bits. Il y a 1 sur 255 possibilités qu'un emplacement aléatoire de la mémoire soit faux, et cela explique pourquoi vous avez perçu la valeur booléenne par défaut comme vraie.

8
Salvatore Previti

Leurs valeurs par défaut ne sont pas définies. Vous ne devez pas vous fier à ce qu'ils soient définis comme une chose ou une autre et sont souvent appelés "ordures".

Selon votre compilateur, il peut être défini sur false. Mais même alors, il vaut mieux les régler.

3
Donald Miner

@Praetorian: couvert les principaux points de sa réponse.

Mais il convient également de le noter.

blah exampleArray[4];         // static storage duration will be zero-initialized 
                              // ie POD member exampleVar will be false.

void foo()
{
    blah exampleArray1[4];    // automatic storage duration will be untouched.
                              // Though this is a class type it only has a compiler 
                              // generated constructor. When it is called this way 
                              // it performs default-construction and POD members
                              // have indeterminate values


    blah exampleArray2[4] = {};  // Can force zero-in initialization;
                                 // This is list-initialization.
                                 // This forces value-initialization of each member.
                                 // If this is a class with a compiler generated constrcutor
                                 // Then each member is zero-initialized


    // following through to non array types.
    blah       tmp1;            // Default initialized: Member is indeterminate
    blah       tmp2 = blah();   // Zero Initialized: Members is false

    // Unfortunately does not work as expected
    blah       tmp3();          // Most beginners think this is zero initialization.
                                // Unfortunately it is a forward function declaration.
                                // You must use tmp2 version to get the zero-initialization 
}
2
Martin York

La valeur par défaut est indéterminée. Peut-être différent à chaque fois que vous exécutez votre programme. Vous devez initialiser la valeur à quelque chose ou avoir une autre variable indiquant que vos membres privés ne sont pas initialisés.

2
FailedDev

Indéterminé.

Les variables membres non statiques doivent être initialisées, sauf si vous pouvez garantir que la première opération effectuée sur elles sera une écriture. La manière la plus courante serait via le constructeur. Utilisez une liste d'initialisation si vous voulez toujours un constructeur sans arg/no-op:

public:
blah() : exampleVar(false) {}
2
Brian Roach

Les valeurs par défaut non affectées ne sont pas définies en C/C++. Si vous avez besoin d'une valeur spécifique, créez un constructeur pour la classe blah et définissez votre valeur par défaut.

1
ObscureRobot