Я получил следующий код от коллеги, разбитый до минимума, используя выражения Boost :: Signal2 и lambda. Компилируется с g ++ 6.x и g ++ 5.4.1 (последний с аргументом -std = c ++ 11).
Это должно напечатать я: 5 (должно быть 5)
Используя кросс-компилятор gcc 6.4.1 (или 6.1.1) для arm32 (arm-cortexa15-linux-gnueabihf-g ++) и работающий в такой системе, вывод я: 0 (должно быть 5)
Другие архитектуры (x86_64) и компиляторы (gcc 5.4.1) работают как положено.
Когда я перехожу на код, чтобы использовать сигнал вместо слота, все в порядке.
Мои вопросы:
Действительно ли этот код должен надежно выводить i: 5 (должно быть 5), или этот код глючит и работает только случайно?
Или есть ошибка в компиляторе ARM32 gcc6? (GCC 5 работ)
Код:
#include <exception>
#include <iostream>
#include <boost/signals2.hpp>
class LogBuffer : public std::streambuf
{
public:
LogBuffer()
{
}
char m_buf[242 - 20];
};
namespace boost
{
void assertion_failed(char const * p_expr,
char const *,
char const *, long)
{
std::cerr << "FAILED: " << p_expr << std::endl;
}
void assertion_failed_msg(char const *,
char const * msg,
char const *,
char const *, long)
{
std::cerr << "FAILED: " << msg << std::endl;
}
} // namespace boost
void myfunction(void)
{
{
LogBuffer b;
std::cout << "LogBuffer size: " << sizeof(LogBuffer) << std::endl;
}
int i=5;
std::cout << i << std::endl;
auto lambda = [i] { std::cerr << "i: " << i << " (should be 5)" << std::endl; };
boost::signals2::signal<void()>::slot_type slot{lambda};
slot();
}
int main(int argc, char *argv[])
{
myfunction();
}
Компиляция и запуск обеспечивают следующий вывод:
arm-cortexa15-linux-gnueabihf-g++ (GCC) 6.4.1 20170811
Copyright (C) 2017 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
Linux fctj-4a 4.4.109-g68c6f3c-fsm4_axm #1 SMP PREEMPT Fri Feb 2 05:37:09 UTC 2018 armv7l GNU/Linux
LogBuffer size: 256
5
i: 0 (should be 5)
Это похоже на ошибку.
Вы можете уменьшить репродуктор? Сказать,
что произойдет, если вы отключите оптимизацию
что произойдет, если вы удалите LogBuffer?
Что произойдет, если вы удалите слот и использовать его в качестве сигнала
Что произойдет, если вы сохраните сигналы и просто вызовете лямбду напрямую?
Что произойдет, если вы вызываете лямбду перед созданием слота
Что произойдет, если вы даже не создадите слот и не вызовете лямбду напрямую?
Что произойдет, если вы также удалите заголовок signal2.
Что произойдет, если вы завершите работу с обработчиками утверждений (возможно, вы получаете утверждения в то время, когда std::cout
еще не инициализировано // доступно)
Если вы уменьшите его до максимально простого ядра и все равно будете иметь сбой, вы по крайней мере будете знать, следует ли сообщать об ошибке в Boost или GCC.
Это то, что я уже сделал:
Другие будут следовать. Я не уверен, как я могу легко удалить заголовок signal2
Райнер