2012-07-26 145 views
1

我有一个C++项目,使用marray库。目前它在Windows 7 x64上使用MinGW g ++ 4.7和msvc2010进行编译和运行,Linux Mint x64上也使用g ++ 4.7进行编译和运行。我决定尝试一下Linux的英特尔C++编译器v。12.1.4。它能够编译代码,但是当它试图执行任何干扰表达式模板的行时(如c = a + b,其中所有三个项都是矩阵),它就会随着分段错误而崩溃。此问题影响应用程序的调试版本和发行版本。英特尔C++编译器无法处理深层模板?

我也尝试编译marray库的单元测试和教程代码,再次,英特尔C++编译代码,但如果它具有任何表达式模板,则无法运行它。英特尔C++真的和深度模板一样糟糕,还是我错过了一些东西?我是否需要设置任何特殊的编译器标志来使模板表达式工作?或者,也许这只是我使用的特定库的错误,而不是一般的表达式模板技术?

我也试图设置使用各种各样的-ftemplate-深度 - ň国旗上的10^10 ň达大得离谱的价值,并且仍然在运行既不是我的应用程序没有运气也没有marray单元测试/教程没有分段错误。

更新:以下是在调试模式下使用icpc编译的所提及库中的tutorial-marray的gdb日志。

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) 

看起来问题并不来自表达式模板技术,数字的数组运算正常。当我试图将一个数组添加到另一个时,问题就出现了。

Upd。 2:其实整个事情看起来很像提到here的问题。解决方案应该在重写操作符E &(){return static_cast(* this); }成为像E & get_ref(){返回static_cast(* this); }和const引用一样。当然,在代码中改变这些东西的用法。将尽快尝试并报告结果。

+0

您能否提供示例代码? – Mehrdad 2012-07-26 21:22:01

+0

我提供了一个[marray]的链接(https://github.com/bjoern-andres/marray),它有一个tutorial.cxx文件,可以作为示例代码,特别是只要它与英特尔编译器为我自己的代码。 – Dmitry 2012-07-26 21:32:06

+0

@Dmitry如果tutorial.cxx segfaults,你能告诉我们在哪里? – 2012-07-26 21:47:11

回答

3

该问题类似于报道的here。这个问题的实际原因是,英特尔C++编译器生成的代码处理这样的表述:该运营商的

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

的递归调用。简单的解决方法是改变操作者进入方法等

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

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

+0

非常好!如果您可以将特定于编译器的代码贡献给[Marray on github](https://github.com/bjoern-andres/marray),理想情况下使用预编译器来识别英特尔的C++编译器,那将是非常好的。 – 2012-09-10 04:04:57

+0

作为我对开源项目的第一个贡献,这将是我的荣幸)所以好吧,我会在几天内完成这个任务。 我也使用一些其他修改为您的精彩库,性能改进和OpenMP支持一点点。如果需要,也可以贡献它(与英特尔C++修补程序分开)。 – Dmitry 2012-09-10 07:05:43

+0

太棒了,我有类似的问题,并一直在寻找解决方案很长一段时间。 – xis 2013-06-26 16:34:43