1

我有一个使用marray库的 C++ 项目。目前,它可以在 Windows 7 x64 上使用 MinGW g++ 4.7 和 msvc2010 以及在 Linux Mint x64 上使用 g++ 4.7 进行编译和运行。我决定尝试一下适用于 Linux 的 Intel C++ compiler v. 12.1.4。它能够编译代码,但是当它尝试执行任何干扰表达式模板的行时(如 c = a + b 其中所有三个项都是矩阵),它会因分段错误而崩溃。此问题会影响应用程序的调试和发布版本。

我还尝试为 marray 库编译单元测试和教程代码,英特尔 C++ 编译代码但如果它有任何表达式模板则无法运行它。英特尔 C++ 是否真的与深度模板一样糟糕,还是我遗漏了什么?我是否需要设置任何特殊的编译器标志才能使模板表达式起作用?或者也许只是我正在使用的特定库有问题,而不是一般的表达式模板技术?

我还尝试在 n 上使用各种各样的 -ftemplate-depth- n 标志设置10 ^ 10的大得可笑的值,并且在没有分段错误的情况下运行我的应用程序和 marray 单元测试/教程仍然没有运气。

更新:这是来自上述库的教程-marray 的 gdb 日志,该库在调试模式下使用 icpc 编译。

GNU gdb (Ubuntu/Linaro 7.3-0ubuntu2) 7.3-2011.08
Copyright (C) 2011 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://bugs.launchpad.net/gdb-linaro/>...
Reading symbols from /home/dmitry/SOFT/Development/marray_orig/tutorial-marray...done.
(gdb) l 126
121                 size_t shape[] = {3, 4, 2};
122                 marray::Marray<int> a(shape, shape + 3, 2);
123                 marray::Marray<int> b(shape, shape + 3, 2);
124                 marray::Marray<int> c;
125
126                 ++a;
127                 --a;
128
129                 a += 2;
130                 a -= 2;
(gdb) break 126
Breakpoint 1 at 0x452de8: file /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx, line 126.
(gdb) run
Starting program: /home/dmitry/SOFT/Development/marray_orig/tutorial-marray 
A(c,r,0) =
1 0 0 
0 0 0 
0 0 0 
0 0 0 

A(c,r,1) =
0 0 0 
0 0 0 
0 0 0 
0 0 2 

1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 
1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 2 

Breakpoint 1, main () at /home/dmitry/SOFT/Development/marray_orig/marray/src/tutorial/tutorial.cxx:126
126                 ++a;
(gdb) next
127                 --a;
(gdb) next
129                 a += 2;
(gdb) next
130                 a -= 2;
(gdb) next
131                 a /= 2;
(gdb) next
132                 a *= 2;
(gdb) next
134                 c = a + b;
(gdb) next

Program received signal SIGSEGV, Segmentation fault.
0x0000000000420fcf in marray::ViewExpression<marray::View<int, false, std::allocator<unsigned long> >, int>::operator marray::View<int, false, std::allocator<unsigned long> > const& (this=0x7fffffffcd88)
at /home/dmitry/SOFT/Development/marray_orig/marray/include/marray/marray.hxx:5409
5409            { return static_cast<const E&>(*this); }
(gdb) 

看起来问题一般不是源于表达式模板技术,数字数组算术工作正常。当我尝试将一个数组添加到另一个数组时,就会出现问题。

更新。2:实际上整个事情看起来很像这里提到的问题。解决方案应该是重写 operator E&() { return static_cast(*this); } 变成类似 E& get_ref() { return static_cast(*this); 和 const 引用相同。当然,在代码中改变这些东西的用法。我会尽快尝试并报告结果。

4

1 回答 1

3

该问题与此处报告的问题类似。问题的实际原因是英特尔 C++ 编译器生成的代码处理如下表达式:

operator E&() 
{ 
    return static_cast<E&>(*this); 
}

作为此运算符的递归调用。一个简单的解决方法是将运算符更改为类似的方法

E& get_ref()
{
    return static_cast<E&>(*this);
}

缺点是您必须更改使用该运算符的每一行代码。幸运的是,使用提到的marray库并不太难,所以现在我的应用程序以及该库的教程和单元测试都像英特尔 C++ 编译器的魅力一样工作。

于 2012-07-29T12:14:13.840 回答