Слот Boost :: Signals2 с лямбда-выражением завершается неудачно, используя gcc6 на arm32

Я получил следующий код от коллеги, разбитый до минимума, используя выражения 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) работают как положено.

Когда я перехожу на код, чтобы использовать сигнал вместо слота, все в порядке.

Мои вопросы:

  1. Действительно ли этот код должен надежно выводить i: 5 (должно быть 5), или этот код глючит и работает только случайно?

  2. Или есть ошибка в компиляторе 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)

2

Решение

Это похоже на ошибку.

Вы можете уменьшить репродуктор? Сказать,

  • что произойдет, если вы отключите оптимизацию

  • что произойдет, если вы удалите LogBuffer?

  • Что произойдет, если вы удалите слот и использовать его в качестве сигнала

  • Что произойдет, если вы сохраните сигналы и просто вызовете лямбду напрямую?

  • Что произойдет, если вы вызываете лямбду перед созданием слота

  • Что произойдет, если вы даже не создадите слот и не вызовете лямбду напрямую?

  • Что произойдет, если вы также удалите заголовок signal2.

  • Что произойдет, если вы завершите работу с обработчиками утверждений (возможно, вы получаете утверждения в то время, когда std::cout еще не инициализировано // доступно)

Если вы уменьшите его до максимально простого ядра и все равно будете иметь сбой, вы по крайней мере будете знать, следует ли сообщать об ошибке в Boost или GCC.

1

Другие решения

Это то, что я уже сделал:

  1. -O0, -O1: ошибка не отображается i: 5 (должно быть 5)
  2. -O2: ошибка показывает 0 (должно быть 5)
  3. удалить Logbuffer: 5 (должно быть 5)
  4. используя сигнал Сигнал: 0 должно быть 5
  5. вызов лямбды напрямую (5 должно быть 5)
  6. использование i после вызова слота (например, печать): 5 (должно быть 5)
  7. используя i [100]: первый элемент становится нулем, другие не затрагиваются
  8. с использованием компилятора x86_64: 5 должно быть 5

Другие будут следовать. Я не уверен, как я могу легко удалить заголовок signal2

Райнер

0

По вопросам рекламы [email protected]