Передача энергозависимого массива в strncpy

В моем ISR у меня есть буфер, который заполняется USART, поэтому я объявил буфер как volatile:

volatile uint8_t RxBuffer1[BUFFER_LENGTH];

Хорошо, нет проблем. Я считаю, что это стандартная практика.

Где-то в main() мне нужно скопировать часть этого массива, так как массив представляет собой циклический буфер и когда-нибудь в будущем будет уничтожен:

strncpy(Data, RxBuffer1, len);

О, но это нет-нет! мой компилятор покорно говорит мне:

передача аргумента 2 из 'strncpy' отбрасывает квалификатор volatile из целевого типа указателя

поскольку strncpy делает 's2' константным символом *

Я не думаю, что делаю что-то, что не было сделано в качестве стандартной практики. Как мне это сделать правильно?


person user1160866    schedule 20.01.2012    source источник
comment
Вы можете привести его к const char *.   -  person    schedule 20.01.2012
comment
Дин-дин-дин. у нас есть победитель! Спасибо. Это действительно избавило от ошибки, однако я нервничаю по этому поводу. Я действительно просто маскирую проблему или действительно так делают профессионалы?   -  person user1160866    schedule 20.01.2012


Ответы (3)


Приведите аргумент, переданный const char *

person Community    schedule 20.01.2012
comment
Что ж, придется возродить эту тему. Я внес некоторые изменения по другим причинам, и теперь эта строка снова не работает. Вот подробности: - person user1160866; 05.02.2012
comment
отбрасывание volatile только заставляет компилятор замолчать, но не решает основную проблему, на которую указывает ошибка. volatile означает, что значения в массиве могут быть изменены вне программы, и сообщает компилятору, что нужно выпустить код, перечитывающий эту память при каждом доступе. - person Arvid; 22.03.2017

Я думаю, что в этом случае лучше использовать memcpy. Strcpy и strncpy оптимизированы для работы со строками (массивами символов).

Синтаксис похож на strncpy:

void* memcpy (void* dest, void* src, size_t bytes);

В твоем случае:

memcpy (Data, RxBuffer1, sizeof(uint8_t) * len);

(вы можете опустить sizeof(uint8_t), так как он равен 1).

person Tibi    schedule 20.01.2012
comment
Нет радости. memcpy делает то же самое, что и strncpy в отношении этой ошибки. Приведение as (const char *) сделало это. - person user1160866; 20.01.2012
comment
Я просто хотел отметить, что да, вы правы, memcpy был бы лучше в этой ситуации, но он просто не решил проблему приведения. Спасибо за помощь. - person user1160866; 20.01.2012

Почти наверняка безопасно отбрасывать volatile, но технически это зависит от компилятора.

Volatile просто говорит компилятору не применять никаких оптимизаций, когда он помещает копию некоторой памяти в регистр и использует ее вместо того, чтобы каждый раз возвращаться и читать память.

В приложении, о котором вы говорите, вас заботит то, что memcpy не должен возвращать те же данные, что и в прошлый раз, когда вы его вызывали, потому что он не перечитал буфер. Но на практике крайне маловероятно, что это будет реализовано таким образом, поскольку это будет означать, что компилятор будет хранить данные в регистрах при вызовах функций. Теоретически это возможно, но особого смысла в этом нет.

И вы почти наверняка не заботитесь о том, чтобы memcpy оптимизировала последующие копии одной и той же памяти в рамках одного вызова memcpy.

person Mike Moreton    schedule 04.10.2013