|
|
  |
модификатор const. Как правильно использовать в Си |
|
|
|
Dec 22 2017, 15:39
|
Знающий
   
Группа: Свой
Сообщений: 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 память.
|
|
|
|
|
Dec 22 2017, 16:29
|

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

|
Цитата(inventor @ Dec 22 2017, 19:21)  может ли компилятор поместить static const не во flash а в памяти данных? Легко. Причём это поведение описано в стандарте. Если у флэша и ОЗУ разные адресные пространства именно так и будет. Например, для AVR специально придуман квалификатор __flash, который укажет компилятору, что данные нужно поместить во флэш, а не в основную память (коей считается ОЗУ). Для ARM, где единое адресное пространство, можно с уверенностью сказать, что static const данные лягут во флэш (кроме случая когда компилятор решит соптимизировать) . Умная книга, которую ТС советовали читать - это стандарт языка Си...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 22 2017, 17:00
|
Знающий
   
Группа: Свой
Сообщений: 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) А линкер может в соответствии со своим скриптом секцию запихнуть туда куда записано в скрипте.
|
|
|
|
|
Dec 22 2017, 17:07
|

неотягощённый злом
     
Группа: Свой
Сообщений: 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; Это я к чему - крутить параметры в скриптах линкера надо не с шашой наголо, а очень и очень вдумчиво...
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Dec 23 2017, 12:07
|
Профессионал
    
Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848

|
Цитата(Raven @ Dec 22 2017, 19:53)  А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH) Я сразу себя приучил, что компилятор мне ничего не "должен"  Особенно в части, если включена оптимизация. И даже если не включена. Есть много платформо-зависимых ньюансов. Разобраться, опятьже, помогает RTFM + работа в отладчике с memory-->View.
|
|
|
|
|
Dec 23 2017, 18:03
|
Знающий
   
Группа: Свой
Сообщений: 524
Регистрация: 25-12-08
Из: Москва
Пользователь №: 42 748

|
то есть для того что бы константные данные легли во flash память необходимо сделать typedef для такого типа: CODE typedef const unsigned char cu8; #define scu8 static cu8
|
|
|
|
|
Dec 23 2017, 19:41
|
Знающий
   
Группа: Свой
Сообщений: 558
Регистрация: 26-11-14
Из: Зеленоград
Пользователь №: 83 842

|
Цитата(demiurg_spb @ Dec 22 2017, 20:07)  Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё. Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.
|
|
|
|
|
Dec 24 2017, 17:36
|

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

|
Цитата(demiurg_spb @ Dec 22 2017, 22:07)  Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё. Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство. ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры. Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ?
|
|
|
|
|
Dec 24 2017, 19:04
|
Гуру
     
Группа: Свой
Сообщений: 3 644
Регистрация: 28-05-05
Пользователь №: 5 493

|
Цитата(juvf @ Dec 24 2017, 20:36)  Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.
ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры.
Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ? хотя бы потому, что ICode и Dcode шины разные, мультплексируются. При выборке из флеша медленого к тому же prefetch работает, размещая константы во флеше он сбросится, итого двойной тормоз выйдет. const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
Эскизы прикрепленных изображений
|
|
|
|
|
Dec 25 2017, 03:10
|
Участник

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

|
Цитата(DASM @ Dec 24 2017, 20:04)  const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать. А почему глобальный конст во флеше, локальный в озу?
Сообщение отредактировал razrab83 - Dec 25 2017, 03:16
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|