La opción g ++ -Wall incluye -Wreorder. Lo que hace esta opción se describe a continuación. No es obvio para mí por qué a alguien le importaría (especialmente lo suficiente como para activar esto por defecto en -Wall).
-Wreorder (solo C ++) Avisar cuando el orden de los inicializadores de miembros dados en el código no coincidir con el orden en que deben ejecutarse. Por ejemplo: struct A { int i; int j; A (): j (0), i (1) {} }; El compilador reorganizará los inicializadores de miembros para i y j para hacer coincidir el orden de declaración de los miembros, emitiendo una advertencia a ese efecto. Esta advertencia está habilitada por -Wall.
c++
g++
compiler-warnings
Peeter Joot
fuente
fuente
-Werror=reorder
Respuestas:
Considerar:
Ahora
i
se inicializa a un valor desconocido, no a cero.Alternativamente, la inicialización de
i
puede tener algunos efectos secundarios para los cuales el orden es importante. P.ejfuente
i
se inicializa1
). Aquí,i
se inicializa enj
, lo que realmente demuestra un problema.El problema es que alguien puede ver la lista de inicializadores miembros en el constructor y pensar que se ejecutan en ese orden (j primero, luego i). No lo son, se ejecutan en el orden en que los miembros se definen en la clase.
Supongamos que escribiste
A(): j(0), i(j) {}
. Alguien podría leer eso y pensar que i termina con el valor 0. No lo hace, porque lo inicializó con j, que contiene basura porque no se ha inicializado.La advertencia le recuerda que debe escribir
A(): i(j), j(0) {}
, que con suerte se ve mucho más sospechoso.fuente
Otras respuestas han proporcionado algunos buenos ejemplos que justifican la opción de una advertencia. Pensé en proporcionar un contexto histórico. El creador de C ++, Bjarne Stroustrup, explica en su libro El lenguaje de programación C ++ (3ra edición, Página 259):
fuente
Esto puede morderte si tus inicializadores tienen efectos secundarios. Considerar:
Lo anterior imprimirá "bar" y luego "foo", aunque intuitivamente uno supondría que el orden es como está escrito en la lista de inicializadores.
Alternativamente, si
x
yy
son de algún tipo definido por el usuario con un constructor, ese constructor también puede tener efectos secundarios, con el mismo resultado no obvio.También puede manifestarse cuando el inicializador de un miembro hace referencia a otro miembro.
fuente
La advertencia existe porque si acaba de leer el constructor, parece que
j
se está inicializando antesi
. Esto se convierte en un problema si uno se usa para inicializar al otro, como enCuando solo miras al constructor, esto parece seguro. Pero en realidad,
j
aún no se ha inicializado en el punto donde se usa para inicializari
, por lo que el código no funcionará como se esperaba. De ahí la advertencia.fuente