реклама на сайте
подробности

 
 
8 страниц V   1 2 3 > »   
Reply to this topicStart new topic
> модификатор const. Как правильно использовать в Си
inventor
сообщение Dec 22 2017, 15:39
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



где компилятор должен расположить "переменные"
такого вида:

CODE
// Описано глобально
const u8 x_pos[][8] = {
{50, 60},
{55, 62, 69, 76, 83, 90, 97, 104},
{76},
{76},
};


то же самое, описано внутри функции


и то же самое внутри функции
CODE

static const u8 x_pos[][8] = {
{50, 60},
{55, 62, 69, 76, 83, 90, 97, 104},
{76},
{76},
};



у меня есть неизменяемый массив большого размера
и при входе в функцию
этот констатный масив создается в стеке.
если его не определить как static
правильно ли это поведение или нет?


в первом варианте в глобальной константе
этот массив помещен в память Flash. Правильное поведение.

Во втором варианте в стек - неправильное
в третьем варианте во Flash память.





Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 22 2017, 16:01
Сообщение #2


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



rtfm, очень нужно почитать умную книжку по языку на котором разрабатываете.

Модификатор const = сообщение компилятору что бы он проследил что бы код в котором определена эта переменная не пытался менять эти данные. Никаких других гарантий просто const не даёт. А еще бывают такие случаи как например volatile const или const register или const - аргумент функции или преобразования типов при которых cv-модификаторы меняются.
Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

Всё увиденное - верное поведение.
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 22 2017, 16:21
Сообщение #3


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



Цитата(Kabdim @ Dec 22 2017, 19:01) *
Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

Всё увиденное - верное поведение.



может ли компилятор поместить static const не во flash а в памяти данных?
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 16:29
Сообщение #4


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(inventor @ Dec 22 2017, 19:21) *
может ли компилятор поместить static const не во flash а в памяти данных?

Легко. Причём это поведение описано в стандарте.
Если у флэша и ОЗУ разные адресные пространства именно так и будет.
Например, для AVR специально придуман квалификатор __flash, который укажет компилятору, что данные нужно поместить во флэш, а не в основную память (коей считается ОЗУ).
Для ARM, где единое адресное пространство, можно с уверенностью сказать, что static const данные лягут во флэш (кроме случая когда компилятор решит соптимизировать) .

Умная книга, которую ТС советовали читать - это стандарт языка Си...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Raven
сообщение Dec 22 2017, 16:53
Сообщение #5


Местный
***

Группа: Свой
Сообщений: 491
Регистрация: 16-01-05
Из: Санкт-Петербург
Пользователь №: 1 987



А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 16:56
Сообщение #6


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Raven @ Dec 22 2017, 19:53) *
Нет не должен т.к. .rodata не всегда ассоциируется с FLASH.
Более того в avr-gcc нет секции .rodata

http://www.nongnu.org/avr-libc/user-manual/mem_sections.html
http://www.nongnu.org/avr-libc/user-manual/malloc.html


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 22 2017, 17:00
Сообщение #7


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(inventor @ Dec 22 2017, 19:21) *
может ли компилятор поместить static const не во flash а в памяти данных?

Теоретически может, но делать этого не будет, т.к. поведение задано настройками.
Если говорить за gcc, то где-то в недрах проекта у вас должен быть файл с расширением *.ld в котором записано что и куда класть. Вы можете его редактировать что бы получить результат отличный от того того что по умолчанию.
Цитата(Raven @ Dec 22 2017, 19:53) *
А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

А линкер может в соответствии со своим скриптом секцию запихнуть туда куда записано в скрипте.
Go to the top of the page
 
+Quote Post
demiurg_spb
сообщение Dec 22 2017, 17:07
Сообщение #8


неотягощённый злом
******

Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643



Цитата(Kabdim @ Dec 22 2017, 20:00) *

Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.
А куда они лягут - об этом более нет ни слова.
Кстати, задумайтесь над тем что будет если константные данные всегда будут лежать во флэш и чем это чревато для архитектуры AVR и не только...

Совершенно легальный код станет невозможен:
Код
char str1[] = "xxx";
const char str2[] = "yyyy";

extern void print_str(const char* str);

print_str(str1);  // норм
print_str(str2);  // попа

Или так будет делать бессмысленно:
Код
volatite const int uptime;

Это я к чему - крутить параметры в скриптах линкера надо не с шашой наголо, а очень и очень вдумчиво...


--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
Go to the top of the page
 
+Quote Post
k155la3
сообщение Dec 23 2017, 12:07
Сообщение #9


Профессионал
*****

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Raven @ Dec 22 2017, 19:53) *
А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

Я сразу себя приучил, что компилятор мне ничего не "должен" sm.gif
Особенно в части, если включена оптимизация. И даже если не включена.
Есть много платформо-зависимых ньюансов.
Разобраться, опятьже, помогает RTFM + работа в отладчике с memory-->View.
Go to the top of the page
 
+Quote Post
inventor
сообщение Dec 23 2017, 18:03
Сообщение #10


Знающий
****

Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748



то есть для того что бы константные данные
легли во flash память необходимо
сделать typedef для такого типа:


CODE
typedef const unsigned char cu8;
#define scu8 static cu8
Go to the top of the page
 
+Quote Post
Kabdim
сообщение Dec 23 2017, 19:41
Сообщение #11


Знающий
****

Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842



Цитата(demiurg_spb @ Dec 22 2017, 20:07) *
Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.

Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 23 2017, 20:24
Сообщение #12


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(Kabdim @ Dec 23 2017, 22:41) *
Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.

ну да, stm8 дешевле.
Go to the top of the page
 
+Quote Post
juvf
сообщение Dec 24 2017, 17:36
Сообщение #13


Профессионал
*****

Группа: Свой
Сообщений: 1 261
Регистрация: 14-05-09
Из: Челябинск
Пользователь №: 49 045



Цитата(demiurg_spb @ Dec 22 2017, 22:07) *
Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.

Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ?
Go to the top of the page
 
+Quote Post
DASM
сообщение Dec 24 2017, 19:04
Сообщение #14


Гуру
******

Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493



Цитата(juvf @ Dec 24 2017, 20:36) *
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.

Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ?

хотя бы потому, что ICode и Dcode шины разные, мультплексируются. При выборке из флеша медленого к тому же prefetch работает, размещая константы во флеше он сбросится, итого двойной тормоз выйдет.
const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
Эскизы прикрепленных изображений
Прикрепленное изображение
 
Go to the top of the page
 
+Quote Post
razrab83
сообщение Dec 25 2017, 03:10
Сообщение #15


Участник
*

Группа: Участник
Сообщений: 52
Регистрация: 5-05-17
Пользователь №: 96 902



Цитата(DASM @ Dec 24 2017, 20:04) *
const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
А почему глобальный конст во флеше, локальный в озу?

Сообщение отредактировал razrab83 - Dec 25 2017, 03:16
Go to the top of the page
 
+Quote Post

8 страниц V   1 2 3 > » 
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 5th July 2025 - 13:11
Рейтинг@Mail.ru


Страница сгенерированна за 0.01496 секунд с 7
ELECTRONIX ©2004-2016