首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Boost::带有lambda表达式的Signals2 2槽使用gcc6在arm32上失败

Boost::带有lambda表达式的Signals2 2槽使用gcc6在arm32上失败
EN

Stack Overflow用户
提问于 2018-02-15 15:46:19
回答 2查看 169关注 0票数 2

我从一位同事那里收到了以下代码,并使用Boost::Signal2 2和lambda表达式将其分解为最小值。它使用g++ 6.x和g++ 5.4.1编译(后者使用参数-std=c++11)。

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

使用gcc 6.4.1 (或6.1.1)交叉编译器arm32 (arm-cortexa15 15-linux-gnueabihf-g++)并在此系统上运行,输出为i: 0(应为5)

其他体系结构(x86_64)和编译器(gcc 5.4.1)按预期工作。

当我改变代码使用一个信号,而不是一个插槽,一切都好。

我的问题是:

  1. 这段代码是否真的能够可靠地输出i: 5(应该是5),还是这段代码是错误的,只是意外地工作了?
  2. 或者ARM32 gcc6编译器中存在bug?(gcc五作品)

代码:

代码语言:javascript
复制
#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();
}   

编译和运行提供了以下输出:

代码语言:javascript
复制
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)
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2018-02-15 23:46:26

看上去像个虫子。

你能减少复制人吗?说,

  • 如果禁用优化,会发生什么?
  • 如果删除LogBuffer会发生什么?
  • 如果您移除插槽并将其用作信号,会发生什么?
  • 如果您保留了信号并直接调用lambda会发生什么?
  • 如果在创建时隙之前调用lambda会发生什么?
  • 如果您甚至不创建插槽并直接调用lambda,会发生什么情况?
  • 如果您还进一步删除signals2头,会发生什么情况。
  • 如果在断言处理程序中终止(可能是在std::cout尚未初始化//可用时获得断言),会发生什么?

如果你把它减少到最简单的核心,并且仍然有故障,你至少会知道是在Boost还是GCC的时候提交一个bug。

票数 1
EN

Stack Overflow用户

发布于 2018-02-16 07:28:23

我已经这样做了:

  1. -O0,-O1: bug没有显示i: 5(应该是5)
  2. -O2: bug显示0(应该是5)
  3. 删除日志缓冲区:5(应该是5)
  4. 使用信号信号:0应该是5
  5. 直接调用lambda (5应该是5)
  6. 调用插槽后使用i(例如打印):5(应该是5)
  7. 使用i100:第一个元素变为零,其他元素不受影响
  8. 使用x86_64编译器:5应该是5

其他人也会跟着做。我不知道如何轻松移除signals2头

雷纳

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48811101

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档