Когда я читал исходный код seastar , я заметил, что существует структура объединения, tx_side
которая имеет только один член. Это какой-то хак для решения определенной проблемы?
К вашему сведению, я вставляю tx_side
структуру ниже:
union tx_side {
tx_side() {}
~tx_side() {}
void init() { new (&a) aa; }
struct aa {
std::deque<work_item*> pending_fifo;
} a;
} _tx;
union
вместоstruct
одного или нескольких различий между ними. Это довольно непонятная методика, поэтому, если не появится оригинальный автор этого кода, я не уверен, что кто-то может дать вам авторитетный ответ, какую проблему они надеются решить с этим (если есть).Ответы:
Потому
tx_side
что это объединение, котороеtx_side()
не инициализирует / не создает автоматическиa
и~tx_side()
не разрушает его автоматически. Это позволяет детально контролировать время жизниa
иpending_fifo
, с помощью размещения новых и ручных вызовов деструкторов (бедняковstd::optional
).Вот пример:
Здесь
B b;
ничего не печатается, потому чтоa
не построено и не разрушено.Если
B
былstruct
,B()
назвал быA()
и~B()
назвали бы~A()
, и вы не смогли бы предотвратить это.источник
int
вы можете получить0xCCCCCCCC
. Чтение неинициализированных данных является неопределенным поведением, и может случиться так, что компилятор просто отбрасывает попытку. Это не просто теория. Debian сделал именно эту ошибку, и это нарушило их реализацию OpenSSL. У них было несколько реальных случайных байтов, они добавили неинициализированную переменную, и компилятор сказал: «Ну, результат не определен, поэтому он также может быть нулевым». Ноль, очевидно, уже не случайный.!= 0
сравнение дало истину. С тех пор я добавил флаги компилятора для обработки неинициализированных переменных как ошибок, чтобы избежать повторного попадания в эту ловушку.Проще говоря, если явно не назначено / не инициализировано значение, объединение с одним членом не инициализирует выделенную память. Эта функциональность может быть достигнута
std:: optional
в C ++ 17.источник