ПроблемаПерекрывающийся доступ 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
}
}