ПроблемаПерекрывающийся доступ restrict
- квалифицированные указатели происходят, когда любой из них верен:
Два restrict
- квалифицированные указатели изменяют объекты, которые имеют перекрывающиеся адреса памяти.
В функции, один или несколько const
restrict
- квалифицированный указатель может изменить nonconst restrict
- квалифицированный указатель, но при вызывании функции, const
и nonconst
аргументы являются тем же самым или выведены из того же указателя.
Стандартная библиотечная функция называется при помощи, ограничивают - квалифицированные указатели то перекрытие.
restrict
- квалифицированный указатель присвоен другому restrict
- квалифицированный указатель в том же осциллографе.
Рискrestrict
спецификатор на указателе подразумевает, что в блоке, только этот указатель (или другие указатели, созданные из этого указателя), могут получить доступ к резкому объекту. Вы не можете создать второй указатель независимо от restrict
- квалифицированный указатель, чтобы указать на объект.
Эта спецификация требует тех двух restrict
- квалифицированные указатели не могут указать на те же или перекрывающиеся объекты. Два restrict
- квалифицированные указатели, получающие доступ к тому же адресу памяти или объекту, приводят к неопределенному поведению.
ИсправлениеЕсли вы присваиваете restrict
- квалифицированный указатель на другой указатель, убедитесь, что самим целевым указателем не является restrict
- квалифицированный. restrict
спецификатор помогает компилятору в оптимизации кода. Удаление всех экземпляров этого спецификатора не изменяет заметное поведение кода.
Пример — присвоение между restrict
- квалифицированные указатели в том же осциллографеint *restrict rptr1;
int *restrict rptr2;
int * ptr;
extern int arr[];
void func (void)
{
arr[0] = 0;
arr[1] = 1;
rptr1 = &arr[0];
rptr2 = &arr[1];
rptr2 = rptr1; //Non-compliant
ptr = rptr1; //Compliant
/* ... */
}
В этом примере, rptr1
и rptr2
restrict
- квалифицированные указатели, которые указывают на другие места в том же массиве arr
. Присвоение одного такого restrict
- квалифицированный указатель на другого в том же осциллографе вызывает нарушение правила.
Пример — restrict
- Квалифицированные параметры функции#include <stddef.h>
#include <stdio.h>
void addArray (size_t n, int *restrict res,
const int *restrict lhs, const int *restrict rhs)
{
for (size_t i = 0; i < n; ++i) {
res[i] = lhs[i] + rhs[i];
}
}
void foo (void)
{
int a[100];
memset(&a, 0, 100);
addArray (100, a, a, a);//Noncompliant
}
В этом примере, функциональном addArray()
задан с тремя restrict
квалифицированные параметры lhs
, rhs
, и res
. Параметры lhs
и rhs
const restrict
указатели. Функциональный addArray()
затем вызывается при помощи того же указателя a
как все три параметра. В результате const restrict
квалифицированные указатели lhs
и rhs
может попытаться получить доступ к памяти, сопоставленной с non-const
restrict
квалифицированный указатель res
. Этот перекрывающийся доступ между lhs
и res
а также это между rhs
и res
неопределенные поведения. Polyspace® повышения два нарушения на вызове функции.
Пример — вызывающий библиотечные функции при помощи restrict
- Квалифицированные Указатели#include <string.h>
void func(void) {
char c_str[]= "test string";
char *ptr1 = c_str;
char *ptr2;
ptr2 = ptr1 + 3;
/* Undefined behavior because of overlapping objects */
memcpy(ptr2, ptr1, 6);//Noncompliant
/* ... */
}
В этом примере, функциональном memcpy
имеет два restrict
- квалифицированные указатели как входные параметры Эта функция копируют шесть байтов с местоположения, на которое указывает ptr1
в местоположение, на которое указывает ptr2
. Поскольку расстояние между ptr1
и ptr2
три байта, memcpy
вызов функции приводит к двум restrict
- квалифицированные указатели, пытающиеся изменить перекрывающуюся память. Этот перекрывающийся доступ приводит к неопределенному поведению. Polyspace отмечает вызов memcpy
.
Пример — присвоения между ограниченными указателямиvoid func(void) {
int *restrict p1;
int *restrict p2 = p1; /* Undefined behavior */ //Noncompliant
}
В этом примере, restrict
- квалифицированный указатель p1
присвоен другому restrict
- квалифицированный указатель в том же осциллографе. Такие присвоения приводят к неопределенному поведению, которое отмечает Polyspace. Чтобы решить вопрос, объявите p2
в отдельном вложенном осциллографе. Например:
void func(void) {
int *restrict p1;
{
int *restrict p2 = p1;//Compliant
}
}