Eles não serão nulos se você não inicializar a estrutura.
Snapshot s;// receives no initializationSnapshot s ={};// value initializes all members
O segundo fará com que todos os membros sejam zero, o primeiro os deixa com valores não especificados. Observe que é recursivo:
structParent{Snapshot s;};Parent p;// receives no initializationParent p ={};// value initializes all members
O segundo fará p.s.{x,y}zero. Você não pode usar essas listas agregadas de inicializadores se tiver construtores em sua estrutura. Se for esse o caso, você precisará adicionar uma initalização adequada a esses construtores
structSnapshot{int x;double y;Snapshot():x(0),y(0){}// other ctors / functions...};
Inicializará x e y como 0. Observe que você pode usá x(), y()-lo para desconsiderar seu tipo: Isso é inicialização de valor e, geralmente, gera um valor inicial adequado (0 para int, 0,0 para double, chamando o construtor padrão para usuário definido tipos que possuem construtores declarados pelo usuário, ...). Isso é importante, especialmente se sua estrutura é um modelo.
Roger: Tente usar a estrutura nomeada no inicializador, é o que eu faço e não recebo nenhum aviso no VC 2012: Snapshot s = Snapshot ();
precisa saber é o seguinte
@Johannes Schaub - litb Funcionará Snapshot s = {};para não membros do POD (para zerá-los)?
ontherocks 15/10
2
O C ++ 11 agora permite inicializá-los na definição da estrutura ou classe, assim: struct Snapshot {double x {0}; // com chaves int y = 0; // ou apenas o estilo da velha escola 'por atribuição', que também é realmente de inicialização};
Ikku100
1
É "Instantâneo s = {};" parte do padrão?
21418 Stefan
40
Não, eles não são 0 por padrão. A maneira mais simples de garantir que todos os valores ou o padrão seja 0 é definir um construtor
Snapshot(): x(0), y(0){}
Isso garante que todos os usos do Snapshot tenham valores inicializados.
A desvantagem é que a estrutura não é mais um tipo de POD, porque possui um construtor. Isso interromperá algumas operações, como gravá-lo em um arquivo temporário.
#
16
@ finnw: C ++ 11 corrige isso, embora a estrutura não seja POD, é "layout padrão".
Ben Voigt
19
Em geral, não. No entanto, uma estrutura declarada como escopo do arquivo ou estática em uma função / será / inicializada em 0 (assim como todas as outras variáveis desses escopos):
int x;// 0int y =42;// 42struct{int a, b;} foo;// 0, 0void foo(){struct{int a, b;} bar;// undefinedstaticstruct{int c, d;} quux;// 0, 0}
Isso realmente não é uma suposição segura. você não deve contar com o valor de qualquer coisa que você não inicializou
Hasturkun
24
Os objetos de duração de armazenamento estático são sempre inicializados em zero - consulte stackoverflow.com/questions/60653/… para obter uma citação do padrão. Se isso é bom estilo é outra questão.
bdonlan
12
Com POD você também pode escrever
Snapshot s ={};
Você não deve usar o memset em C ++, o memset tem a desvantagem de que, se houver um não-POD na estrutura, ele o destruirá.
ou assim:
struct init
{template<typename T>operator T *(){returnnew T();}};Snapshot* s = init();
@Andy A maioria dos vexing Parse transforma coisas que se parecem com citores normais - SomeType foo();é o típico, embora possa acontecer com outras pessoas - em definições de função (nesse caso, uma função fooque retorna SomeType). Sinto muito pelo necro, mas se alguém mais se deparar com isso, achei que eu responderia.
Fund Monica's Lawsuit
7
No C ++, use construtores sem argumento. Em C, você não pode ter construtores; portanto, use um memsetou - a solução interessante - inicializadores designados:
Eu acredito que isso é C, não C ++. Falha ao compilar sob alguns compiladores C ++. Eu experimentei a falha de compilação sob Cygwin ou MinGW.
JWW
3
Acredito que a resposta correta é que seus valores são indefinidos. Geralmente, eles são inicializados como 0 ao executar versões de depuração do código. Geralmente, esse não é o caso ao executar versões de lançamento.
O mesmo vale para o dobro; all-bits-zero não é necessariamente 0.0. No entanto, você pode verificar se possui dobras IEEE754; nesse caso, ele deve funcionar.
MSalters
1
Mova os membros do pod para uma classe base para reduzir sua lista de inicializadores:
Respostas:
Eles não serão nulos se você não inicializar a estrutura.
O segundo fará com que todos os membros sejam zero, o primeiro os deixa com valores não especificados. Observe que é recursivo:
O segundo fará
p.s.{x,y}
zero. Você não pode usar essas listas agregadas de inicializadores se tiver construtores em sua estrutura. Se for esse o caso, você precisará adicionar uma initalização adequada a esses construtoresInicializará x e y como 0. Observe que você pode usá
x(), y()
-lo para desconsiderar seu tipo: Isso é inicialização de valor e, geralmente, gera um valor inicial adequado (0 para int, 0,0 para double, chamando o construtor padrão para usuário definido tipos que possuem construtores declarados pelo usuário, ...). Isso é importante, especialmente se sua estrutura é um modelo.fonte
Snapshot s = {};
para não membros do POD (para zerá-los)?Não, eles não são 0 por padrão. A maneira mais simples de garantir que todos os valores ou o padrão seja 0 é definir um construtor
Isso garante que todos os usos do Snapshot tenham valores inicializados.
fonte
Em geral, não. No entanto, uma estrutura declarada como escopo do arquivo ou estática em uma função / será / inicializada em 0 (assim como todas as outras variáveis desses escopos):
fonte
Com POD você também pode escrever
Você não deve usar o memset em C ++, o memset tem a desvantagem de que, se houver um não-POD na estrutura, ele o destruirá.
ou assim:
fonte
SomeType foo();
é o típico, embora possa acontecer com outras pessoas - em definições de função (nesse caso, uma funçãofoo
que retornaSomeType
). Sinto muito pelo necro, mas se alguém mais se deparar com isso, achei que eu responderia.No C ++, use construtores sem argumento. Em C, você não pode ter construtores; portanto, use um
memset
ou - a solução interessante - inicializadores designados:fonte
Acredito que a resposta correta é que seus valores são indefinidos. Geralmente, eles são inicializados como 0 ao executar versões de depuração do código. Geralmente, esse não é o caso ao executar versões de lançamento.
fonte
0
esses lugares na memória. Isso não é o mesmo que inicialização!Como este é um POD (essencialmente uma estrutura C), há pouco dano em inicializá-lo da maneira C:
ou similar
Eu não iria tão longe a ponto de usar
calloc()
em um programa C ++.fonte
Mova os membros do pod para uma classe base para reduzir sua lista de inicializadores:
fonte