Компилятор Intel C++ не может обрабатывать глубокие шаблоны?

У меня есть проект на C++ с использованием библиотеки marray. На данный момент он прекрасно компилируется и работает с MinGW g++ 4.7 и msvc2010 в Windows 7 x64, а также с g++ 4.7 в Linux Mint x64. Я решил попробовать компилятор Intel C++ версии 12.1.4 для Linux. Он смог скомпилировать код, но когда он пытается выполнить любую строку, мешающую шаблонам выражений (например, c = a + b, где все три термина являются матрицами), он ломается из-за ошибки сегментации. Эта проблема затрагивает как отладочную, так и выпускную версии приложения.

Я также попытался скомпилировать модульные тесты и учебный код для библиотеки marray, и снова Intel C++ компилирует код, но не может его запустить, если у него есть какие-либо шаблоны выражений. Действительно ли Intel C++ так плох с глубокими шаблонами или я что-то упускаю? Нужно ли устанавливать какие-либо специальные флаги компилятора, чтобы выражения шаблона работали? Или, может быть, это просто что-то не так с конкретной библиотекой, которую я использую, а не с техникой шаблонов выражений в целом?

Я также пытался установить флаг -ftemplate-depth-n, используя самые разные значения n вплоть до смехотворно большие значения 10 ^ 10, и мне все еще не удавалось запустить ни мое приложение, ни модульные тесты/учебник marray без ошибки сегментации.

Обновление: Вот лог gdb для tutorial-marray из упомянутой библиотеки, скомпилированный с помощью 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: На самом деле все выглядит очень похоже на проблему, упомянутую здесь< /а>. Решение должно заключаться в переписывании оператора E&() { return static_cast(*this); } во что-то вроде E& get_ref() { return static_cast(*this); } и то же самое для ссылки на константу. И, конечно же, изменить использование этих вещей в коде. Попробую, как только смогу, и сообщу о результатах.


person Dmitry    schedule 26.07.2012    source источник
comment
Не могли бы вы предоставить пример кода?   -  person user541686    schedule 27.07.2012
comment
Я предоставил ссылку на marray, там есть файл tutorial.cxx, который может служить образцом код, особенно если он имеет ту же проблему с компилятором Intel, что и мой собственный код.   -  person Dmitry    schedule 27.07.2012
comment
@DmitryDmitry, если tutorial.cxx дает сбой сегментации, можете ли вы показать нам, где?   -  person Drew Dormann    schedule 27.07.2012
comment
Добавлена ​​ссылка на проблему, которая выглядит аналогично тому, где было найдено обходное решение. . Попробую это, как только смогу (что, к сожалению, не так скоро) и вернусь с отчетом.   -  person Dmitry    schedule 27.07.2012


Ответы (1)


Проблема аналогична той, о которой сообщалось здесь. Фактическая причина проблемы заключается в том, что код, сгенерированный компилятором Intel C++, обрабатывает такие выражения:

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

как рекурсивные вызовы этого оператора. Простой обходной путь - изменить оператор на метод, например

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

Недостатком является то, что вам нужно изменить каждую строку кода, в которой используется этот оператор. К счастью, с упомянутой библиотекой marray это оказалось не слишком сложно, так что теперь и мое приложение, и учебные пособия и модульные тесты этой библиотеки прекрасно работают с компилятором Intel C++.

person Dmitry    schedule 29.07.2012
comment
Очень хорошо! Было бы здорово, если бы вы могли добавить код, специфичный для компилятора, в Marray на github, в идеале используя предварительный компилятор для идентификации компилятора Intel C++. - person ; 10.09.2012
comment
Это было бы честью для меня как мой первый вклад в проект с открытым исходным кодом ) Так что ок, сделаю это через пару дней. Я также использую некоторые другие модификации для вашей замечательной библиотеки, небольшое улучшение производительности и поддержку OpenMP. При необходимости могу внести свой вклад (отдельно от исправления Intel C++). - person Dmitry; 10.09.2012
comment
отлично, у меня была похожая проблема, и я долго искал решение. - person xis; 26.06.2013