Во-первых, cppreference говорит об ограничении следующее:
Во время каждого выполнения блока, в котором объявлен ограниченный указатель P (обычно при каждом выполнении тела функции, в котором P является параметром функции), если какой-либо объект, доступный через P (прямо или косвенно), модифицируется любым способом. , то все обращения к этому объекту (как чтение, так и запись) в этом блоке должны происходить через P (прямо или косвенно), в противном случае поведение не определено.
Но под этим абзацем написано:
Ограниченные указатели могут свободно назначаться неограниченным указателям, возможности оптимизации сохраняются до тех пор, пока компилятор может анализировать код:
void f(int n, float * restrict r, float * restrict s) {
float * p = r, * q = s; // OK
while(n-- > 0) *p++ = *q++; // almost certainly optimized just like *r++ = *s++
}
В приведенном выше примере r[0]
является объектом, доступным через ограниченный указатель r
, и доступ к нему осуществляется через p
, что, кажется, противоречит первому абзацу (что доступ к r[0]
должен осуществляться исключительно через r
)?
Второй:
Присвоение одного ограниченного указателя другому является неопределенным поведением, за исключением случаев, когда присваивается указатель на объект в некотором внешнем блоке указателю в некотором внутреннем блоке (включая использование аргумента ограниченного указателя при вызове функции с ограниченным параметром указателя) или когда возврат из функции (и в противном случае, когда блок указателя from закончился).
Итак, подходит ли следующий код?
void foo(char* restrict a, size_t s)
{
for(char* restrict aa = a; aa < a + s; ++aa) // Is aa in an inner block?
{
*aa = '\0';
}
}
for
номинально представляет собой блок вокруг циклаwhile
, так что все должно быть в порядке. - person Kerrek SB   schedule 14.03.2017restrict
— это просто договор между программистом и компилятором. Обнаруживrestrict
квалифицированные указатели в качестве параметров функции, программист должен пообещать компилятору, что он не будет передавать этой функции два параметра, которые перекрываются в памяти. Если компилятор может предположить это, ему не нужно будет включать дополнительный служебный код для обработки перекрытий. Но ничто не заставляет компилятор давать диагностику, если программист нарушает этот контракт. Вот как это происходит, когда в комитете по стандарту C присутствует слишком много компиляторов... - person Lundin   schedule 14.03.2017