gcc C/C++ не предполагает псевдонимов указателей
Недавно прочитав, что основная причина того, что fortran быстрее, чем c/ C++ в числовых вычислениях, заключается в том, что нет псевдонимов указателей.
Видимо, используя restrict
или же __restrict__
ключевые слова позволяют в каждом конкретном случае указывать на отсутствие наложения указателей для данного элемента памяти.
Компилятор icc, по-видимому, имеет опцию -fno-alias
что позволяет глобально предположить, что псевдонимов нет. На gcc есть -fno-strict-aliasing
, который применяется только к подмножеству всех ситуаций наложения имен.
Есть ли опция в gcc, или есть ли случаи, когда псевдонимы не предполагаются при использовании определенных флагов оптимизации?
1 ответ
GCC имеет возможность -fstrict-aliasing
который позволяет использовать псевдонимы во всем мире и ожидает, что вы ничего не получите незаконным псевдонимом. Эта оптимизация включена для -O2
а также -O3
Я верю.
C++ имеет четко определенные правила псевдонимов, и совместимый со стандартами код не будет противоречить строгим псевдонимам. В частности это означает, что вы не можете получить доступ к одной переменной через указатель на другой тип:
float f;
int * p = reinterpret_cast<int*>(&f); // uh-oh
*p = 0x3FF00000; // breaks strict aliasing
Важнейшим исключением из этого правила является то, что вы всегда можете получить доступ к любой переменной через указатель на char
, (Это необходимо для сериализации через операции ввода-вывода.)
Правила псевдонимов не помогают компилятору узнать, существуют ли какие-либо указатели одинакового типа с псевдонимами друг друга. Учти это:
void add(float * a, float * b, float * c) { *c = *a + *b; }
Здесь компилятор не может знать, c
указывает на другую память, чем a
или же b
и должен быть осторожен. Я думаю это где restrict
имеет значение, по сути, обещая, что float * restrict c
означает, что никто не псевдонимы c
,