¿Los miembros de una estructura de C++ se inicializan en 0 de forma predeterminada?

5 minutos de lectura

tengo esto struct:

struct Snapshot
{
    double x; 
    int y;
};

quiero x y y a ser 0. ¿Serán 0 por defecto o tengo que hacer:

Snapshot s = {0,0};

¿Cuáles son las otras formas de poner a cero la estructura?

  • Utilice un std::map y devuelva 0 cuando no exista una clave.

    – Jonny

    5 de abril de 2016 a las 7:12

  • Tenga en cuenta que el uso de valores indeterminados es un comportamiento indefinido

    – Shafik Yaghmour

    25 de febrero de 2019 a las 11:04

¿Los miembros de una estructura de C++ se inicializan en 0 de forma predeterminada?
Johannes Schaub – litb

No son nulos si no inicializa la estructura.

Snapshot s; // receives no initialization
Snapshot s = {}; // value initializes all members

El segundo hará que todos los miembros sean cero, el primero los deja en valores no especificados. Tenga en cuenta que es recursivo:

struct Parent { Snapshot s; };
Parent p; // receives no initialization
Parent p = {}; // value initializes all members

El segundo hará p.s.{x,y} cero. No puede usar estas listas de inicializadores agregados si tiene constructores en su estructura. Si ese es el caso, deberá agregar la inicialización adecuada a esos constructores

struct Snapshot {
    int x;
    double y;
    Snapshot():x(0),y(0) { }
    // other ctors / functions...
};

Inicializará tanto x como y a 0. Tenga en cuenta que puede usar x(), y() para inicializarlos sin tener en cuenta su tipo: eso es entonces la inicialización del valor, y generalmente produce un valor inicial adecuado (0 para int, 0.0 para doble, llamando al constructor predeterminado para tipos definidos por el usuario que tienen constructores declarados por el usuario, …). Esto es importante especialmente si su estructura es una plantilla.

  • Esto produce muchas advertencias en mi compilador.

    – River-Claire Williamson

    22 de marzo de 2013 a las 18:26

  • Roger: Trate de usar la estructura con nombre en el inicializador, eso es lo que hago y no recibo ninguna advertencia en VC 2012: Instantánea s = Instantánea ();

    – Kit10

    19 de agosto de 2013 a las 14:10


  • @Johannes Schaub – litb Voluntad Snapshot s = {}; trabajo para no miembros de POD (para ponerlos a cero)?

    – con hielo

    15 de octubre de 2013 a las 9:58


  • C++11 ahora le permite inicializarlos en la definición de la estructura o clase, así: struct Snapshot { double x{0}; //con llaves int y = 0; // o simplemente el estilo de la vieja escuela ‘por asignación’, que también es una inicialización };

    – ikku100

    5 mayo 2016 a las 17:36


  • Es “Instantánea s = {};” parte de la norma?

    – Stefan

    17 de julio de 2018 a las 13:42

No, no son 0 por defecto. La forma más sencilla de garantizar que todos los valores o por defecto sean 0 es definir un constructor

Snapshot() : x(0), y(0) {
}

Esto asegura que todos los usos de Snapshot tendrán valores inicializados.

  • La desventaja es que la estructura ya no es un tipo POD, porque tiene un constructor. Eso interrumpirá algunas operaciones, como escribirlo en un archivo temporal.

    – finlandés

    1 de julio de 2009 a las 15:12

  • @finnw: C++ 11 corrige esto, aunque la estructura no es POD, es “diseño estándar”.

    – Ben Voigt

    4 de agosto de 2012 a las 23:08

En general, no. Sin embargo, una estructura declarada como ámbito de archivo o estática en una función /se/se inicializará en 0 (al igual que todas las demás variables de esos ámbitos):

int x; // 0
int y = 42; // 42
struct { int a, b; } foo; // 0, 0

void foo() {
  struct { int a, b; } bar; // undefined
  static struct { int c, d; } quux; // 0, 0
}

  • Eso realmente no es una suposición segura. no debe confiar en el valor de nada que no haya inicializado

    – Hasturkun

    1 de julio de 2009 a las 16:02

  • Los objetos de duración de almacenamiento estático siempre se inicializan en cero; consulte stackoverflow.com/questions/60653/… para obtener una cita del estándar. Si esto es buen estilo es otra cuestión.

    – bdonlan

    1 de julio de 2009 a las 16:13

¿Los miembros de una estructura de C++ se inicializan en 0 de forma predeterminada?
andersk

Con POD también puedes escribir

Snapshot s = {};

No debe usar memset en C ++, memset tiene el inconveniente de que si hay un no POD en la estructura, lo destruirá.

o así:

struct init
{
  template <typename T>
  operator T * ()
  {
    return new T();
  }
};

Snapshot* s = init();

En C++, use constructores sin argumentos. En C no puedes tener constructores, así que usa cualquiera memset o – la solución interesante – inicializadores designados:

struct Snapshot s = { .x = 0.0, .y = 0.0 };

  • Creo que esto es C, no C++. No se podrá compilar con algunos compiladores de C++. Experimenté el error de compilación en Cygwin o MinGW.

    – jww

    12 de agosto de 2015 a las 7:50

  • Esto funcionará en C o C++20. En los estándares C++ más antiguos, solo funcionará si su compilador es amable.

    – EinfachPeaje

    28 de enero de 2021 a las 11:57

¿Los miembros de una estructura de C++ se inicializan en 0 de forma predeterminada?
finlandés

Dado que se trata de un POD (esencialmente una estructura C), hay poco daño al inicializarlo de la manera C:

Snapshot s;
memset(&s, 0, sizeof (s));

o similar

Snapshot *sp = new Snapshot;
memset(sp, 0, sizeof (*sp));

Yo no iría tan lejos como para usar calloc() aunque en un programa C++.

  • Creo que esto es C, no C++. No se podrá compilar con algunos compiladores de C++. Experimenté el error de compilación en Cygwin o MinGW.

    – jww

    12 de agosto de 2015 a las 7:50

  • Esto funcionará en C o C++20. En los estándares C++ más antiguos, solo funcionará si su compilador es amable.

    – EinfachPeaje

    28 de enero de 2021 a las 11:57

¿Los miembros de una estructura de C++ se inicializan en 0 de forma predeterminada?
eric

Creo que la respuesta correcta es que sus valores no están definidos. A menudo, se inicializan en 0 cuando se ejecutan versiones de depuración del código. Este no suele ser el caso cuando se ejecutan versiones de lanzamiento.

  • En realidad, las versiones de depuración ya tienen 0 en esos lugares en la memoria. ¡Esto no es lo mismo que la inicialización!

    – Carreras de ligereza en órbita

    17 de enero de 2012 a las 16:04

¿Ha sido útil esta solución?