Cuando estaba leyendo el código fuente de Seastar , noté que hay una estructura de unión llamada tx_side
que tiene un solo miembro. ¿Es esto un truco para lidiar con cierto problema?
FYI, pego la tx_side
estructura a continuación:
union tx_side {
tx_side() {}
~tx_side() {}
void init() { new (&a) aa; }
struct aa {
std::deque<work_item*> pending_fifo;
} a;
} _tx;
union
lugar destruct
es una o más de las diferencias entre los dos. Es una técnica bastante oscura, así que a menos que aparezca el autor original de ese código, no estoy seguro de que alguien pueda darle una respuesta autorizada sobre el problema que esperan resolver con esto (si lo hay).Respuestas:
Porque
tx_side
es una unión,tx_side()
no se inicializa / construye automáticamentea
, y~tx_side()
no la destruye automáticamente. Esto permite un control detallado sobre la vida útil de ,a
ypending_fifo
mediante la colocación de nuevas llamadas destructoras manuales y (un hombre pobrestd::optional
).Aquí hay un ejemplo:
Aquí,
B b;
no imprime nada, porquea
no se construye ni se destruye.Si
B
fuera unstruct
,B()
llamaríaA()
y~B()
llamaría~A()
, y usted no podría evitarlo.fuente
int
, puede obtener0xCCCCCCCC
. La lectura de datos no inicializados es Comportamiento indefinido, y lo que podría suceder es que el compilador simplemente descarta el intento. Esto no es solo teoría. Debian cometió este error exacto y rompió su implementación de OpenSSL. Tenían algunos bytes aleatorios reales, agregaron una variable no inicializada y el compilador dijo "bueno, el resultado no está definido, por lo que podría ser cero". Obviamente, Zero ya no es aleatorio.!= 0
comparación posterior arrojó verdadero. Desde entonces, agregué indicadores de compilación para tratar las variables no inicializadas como errores para asegurarme de que no vuelva a caer en esa trampa.En palabras simples, a menos que se asigne / inicialice explícitamente un valor, la unión de un solo miembro no inicializa la memoria asignada. Esta funcionalidad se puede lograr con
std:: optional
c ++ 17.fuente