Boost.Interprocess:如果使用或不使用优化(GCC)编译,测试用例会给出不同的结果

发布于 2024-12-17 03:34:02 字数 1861 浏览 3 评论 0原文

在进行优化编译时,我在 Boost.Interprocess 分配器方面遇到了一些麻烦。我设法将其缩减为 40 行测试用例,其中大部分是样板文件。只需看一下下面代码中的 create()main() 函数即可。

#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>

namespace interp = boost::interprocess;

struct interp_memory_chunk
{
  interp::managed_shared_memory  chunk;

  interp_memory_chunk ()
  {
    interp::shared_memory_object::remove ("GCC_interprocess_test");
    chunk = interp::managed_shared_memory (interp::create_only, "GCC_interprocess_test", 0x10000);
  }

  ~interp_memory_chunk ()
  {
    interp::shared_memory_object::remove ("GCC_interprocess_test");
  }
};

typedef  interp::allocator <int, interp::managed_shared_memory::segment_manager>  allocator_type;

inline  void
create (allocator_type& allocator, allocator_type::value_type& at, int value)
{
  allocator.construct (allocator.address (at), value);
}

int
main ()
{
  interp_memory_chunk      memory;
  allocator_type           allocator (memory.chunk.get_segment_manager ());
  allocator_type::pointer  data = allocator.allocate (1);

  create (allocator, *data, 0xdeadbeef);
  std::cout << std::hex << *data << "\n";
}

当编译此而不优化

g++ interprocess.cpp -lboost_thread -o interprocess

并运行时,输出为deadbeef,正如预期的那样。

然而,当编译优化时:

g++ -O1 interprocess.cpp -lboost_thread -o interprocess

运行给出0不是预期的结果。

所以,我不确定问题出在哪里。这是我的程序中的错误吗?即我是否调用某些 UB?这是 Boost.Interprocess 中的错误吗?或者也许在海湾合作委员会?

根据记录,我在 GCC 4.6 和 4.5 中观察到了这种行为,但在 GCC 4.4 或 Clang 中没有观察到这种行为。这里的Boost版本是1.46.1。

编辑:请注意,将 create() 作为单独的函数至关重要,这可能表明当 GCC 内联它时会出现问题。

I'm having some troubles with Boost.Interprocess allocators when compiling with optimization. I managed to get this down to a 40 lines testcase, most of which is boilerplate. Just have a look at create() and main() functions in the code below.

#include <iostream>
#include <boost/interprocess/allocators/allocator.hpp>
#include <boost/interprocess/managed_shared_memory.hpp>

namespace interp = boost::interprocess;

struct interp_memory_chunk
{
  interp::managed_shared_memory  chunk;

  interp_memory_chunk ()
  {
    interp::shared_memory_object::remove ("GCC_interprocess_test");
    chunk = interp::managed_shared_memory (interp::create_only, "GCC_interprocess_test", 0x10000);
  }

  ~interp_memory_chunk ()
  {
    interp::shared_memory_object::remove ("GCC_interprocess_test");
  }
};

typedef  interp::allocator <int, interp::managed_shared_memory::segment_manager>  allocator_type;

inline  void
create (allocator_type& allocator, allocator_type::value_type& at, int value)
{
  allocator.construct (allocator.address (at), value);
}

int
main ()
{
  interp_memory_chunk      memory;
  allocator_type           allocator (memory.chunk.get_segment_manager ());
  allocator_type::pointer  data = allocator.allocate (1);

  create (allocator, *data, 0xdeadbeef);
  std::cout << std::hex << *data << "\n";
}

When compiling this without optimization:

g++ interprocess.cpp -lboost_thread -o interprocess

and running, the output is deadbeef, as expected.

However, when compiling with optimization:

g++ -O1 interprocess.cpp -lboost_thread -o interprocess

running gives 0, not what is expected.

So, I'm not sure where the problem is. Is this a bug in my program, i.e. do I invoke some UB? Is it a bug in Boost.Interprocess? Or maybe in GCC?

For the record, I observe this behavior with GCC 4.6 and 4.5, but not with GCC 4.4 or Clang. Boost version is 1.46.1 here.

EDIT: Note that having create() as a separate function is essential, which might indicate that problem arises when GCC inlines it.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

尤怨 2024-12-24 03:34:02

正如其他人所建议的,一种解决方案是尝试找到触发问题所需的最小优化标志集,使用 -O1 -fno...

其他选项:

  1. 使用 Valgrind 并查看它会产生什么结果

  2. 尝试使用“-fdump-tree-all”进行编译,这会生成一堆中间编译文件。然后您可以查看编译后的代码是否有任何差异。这些中间文件仍然是C++语言,所以你不需要了解汇编程序。它们几乎是人类可读的,并且肯定是可比较的。

As others have suggested, one solution is try to find the minimial set of optimisation flags you need to trigger your problem, using -O1 -fno....

Other options:

  1. Use Valgrind and see what it comes up with

  2. Try compiling with "-fdump-tree-all", this generates a bunch of intermediate compiled files. You can then see if the compiled code has any differences. These intermediate files are still in C++, so you don't need to know assembler. They are pretty much human readable, and certainly diffable.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文