A opção g ++ -Wall inclui -Wreorder. O que essa opção faz é descrito abaixo. Não é óbvio para mim por que alguém se importaria (especialmente o suficiente para ativar isso por padrão em -Wall).
-Pedido (apenas C ++) Avisar quando a ordem dos inicializadores de membros fornecida no código não coincidir com a ordem em que eles devem ser executados. Por exemplo: struct A { int i; int j; A (): j (0), i (1) {} }; O compilador irá reorganizar os inicializadores de membros para iej para coincidir com a ordem de declaração dos membros, emitindo um aviso àquele efeito. Este aviso é ativado por -Wall.
c++
g++
compiler-warnings
Peeter Joot
fonte
fonte
-Werror=reorder
Respostas:
Considerar:
Agora
i
é inicializado com algum valor desconhecido, não zero.Como alternativa, a inicialização de
i
pode ter alguns efeitos colaterais para os quais o pedido é importante. Por exemplofonte
i
é inicializado1
). Aqui,i
é inicializado comoj
, o que realmente demonstra um problema.O problema é que alguém pode ver a lista de inicializadores de membros no construtor e pensar que eles são executados nessa ordem (j primeiro, depois i). Eles não são, são executados na ordem em que os membros são definidos na classe.
Suponha que você escreveu
A(): j(0), i(j) {}
. Alguém pode ler isso e pensar que eu acabo com o valor 0. Não, porque você o inicializou com j, que contém lixo eletrônico porque ele próprio não foi inicializado.O aviso lembra que você escreva
A(): i(j), j(0) {}
, que parece muito mais suspeito.fonte
Outras respostas forneceram alguns bons exemplos que justificam a opção de um aviso. Eu pensei em fornecer algum contexto histórico. O criador do C ++, Bjarne Stroustrup, explica em seu livro A linguagem de programação C ++ (3ª edição, página 259):
fonte
Isso pode te morder se seus inicializadores tiverem efeitos colaterais. Considerar:
O texto acima imprimirá "bar" e depois "foo", mesmo que intuitivamente alguém suponha que a ordem seja escrita na lista de inicializadores.
Como alternativa, se
x
ey
são de algum tipo definido pelo usuário com um construtor, esse construtor também pode ter efeitos colaterais, com o mesmo resultado não óbvio.Também pode se manifestar quando o inicializador de um membro faz referência a outro membro.
fonte
O aviso existe porque se você acabou de ler o construtor, parece que ele
j
está sendo inicializado antesi
. Isso se torna um problema se um é usado para inicializar o outro, como emQuando você olha apenas para o construtor, isso parece seguro. Mas, na realidade,
j
ainda não foi inicializado no ponto em que é usado para inicializari
e, portanto, o código não funcionará conforme o esperado. Daí o aviso.fonte