BOOST :: SIGNALS2带有Lambda表达式的SIGNALS2插槽使用ARM32上的GCC6失败

Boost::Signals2 slot with lambda expression fails using gcc6 on arm32

本文关键字:SIGNALS2 ARM32 上的 失败 GCC6 带有 Lambda 表达式 BOOST 插槽      更新时间:2023-10-16

我从同事那里收到以下代码,使用boost :: signal2和lambda表达式分解至最低限度。它使用G 6.x和G 5.4.1编译(后者的参数-std = C 11(。

应该打印 i:5(应该是5(

使用ARM32的GCC 6.4.1(或6.1.1(交叉编译器(ARM-CORTEXA15-LINUX-GNUEAEABIHF-G (并在此类系统上运行,输出为 i:0(应该为5(应该为5((

其他体系结构(X86_64(和编译器(GCC 5.4.1(按预期工作。

当我更改代码以使用信号而不是插槽时,一切都可以。

我的问题是:

  1. 此代码真的应该可靠地输出i:5(应该是5(,还是该代码buggy并只是意外工作?

  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)

看起来像一个错误。

您可以减少生殖器吗?说,

  • 如果您禁用优化

  • 会发生什么情况
  • 如果您删除LogBuffer会发生什么?

  • 如果您删除插槽并将其用作信号

  • 会发生什么情况
  • 如果您保留信号并直接调用lambda会发生什么?

  • 如果您在创建插槽之前调用lambda会发生什么情况

  • 如果您甚至不创建插槽,并直接致电lambda会发生什么?

  • 如果您还会进一步删除Signals2标题,会发生什么。

  • 如果您在断言处理程序中终止会发生什么(也许您会在std::cout尚未初始化//可用时得到断言(

如果将其简化为最简单的核心并仍然有故障,您至少会知道是在Boost还是GCC

上提交错误

这就是我已经做过的:

  1. -o0,-o1:错误不显示I:5(应该是5(
  2. -O2:错误显示0(应该为5(
  3. 删除logbuffer:5(应该是5(
  4. 使用信号信号:0应为5
  5. 直接致电lambda(5为5(
  6. 在调用插槽后使用i(例如打印(:5(应为5(
  7. 使用i [100]:第一个元素变为零,其他元素不受影响
  8. 使用x86_64编译器:5应该是5

其他人会跟随。我不确定如何轻松删除Signals2标头

Reiner