Перейти к содержанию
    

модификатор const. Как правильно использовать в Си

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

такого вида:

 

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

 

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

 

 

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

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

 

 

у меня есть неизменяемый массив большого размера

и при входе в функцию

этот констатный масив создается в стеке.

если его не определить как static

правильно ли это поведение или нет?

 

 

в первом варианте в глобальной константе

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

 

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

в третьем варианте во Flash память.

 

 

 

 

 

 

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

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

 

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

Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно.

 

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

 

 

может ли компилятор поместить static const не во flash а в памяти данных?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может ли компилятор поместить static const не во flash а в памяти данных?

Легко. Причём это поведение описано в стандарте.

Если у флэша и ОЗУ разные адресные пространства именно так и будет.

Например, для AVR специально придуман квалификатор __flash, который укажет компилятору, что данные нужно поместить во флэш, а не в основную память (коей считается ОЗУ).

Для ARM, где единое адресное пространство, можно с уверенностью сказать, что static const данные лягут во флэш (кроме случая когда компилятор решит соптимизировать) .

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Нет не должен т.к. .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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

может ли компилятор поместить static const не во flash а в памяти данных?

Теоретически может, но делать этого не будет, т.к. поведение задано настройками.

Если говорить за gcc, то где-то в недрах проекта у вас должен быть файл с расширением *.ld в котором записано что и куда класть. Вы можете его редактировать что бы получить результат отличный от того того что по умолчанию.

А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

А линкер может в соответствии со своим скриптом секцию запихнуть туда куда записано в скрипте.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.

А куда они лягут - об этом более нет ни слова.

Кстати, задумайтесь над тем что будет если константные данные всегда будут лежать во флэш и чем это чревато для архитектуры 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;

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH)

Я сразу себя приучил, что компилятор мне ничего не "должен" :)

Особенно в части, если включена оптимизация. И даже если не включена.

Есть много платформо-зависимых ньюансов.

Разобраться, опятьже, помогает RTFM + работа в отладчике с memory-->View.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

то есть для того что бы константные данные

легли во flash память необходимо

сделать typedef для такого типа:

 

 

typedef const unsigned char cu8;
#define scu8 static cu8

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.

Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать.

ну да, stm8 дешевле.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.
Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

 

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

 

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

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство.

 

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

 

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

хотя бы потому, что ICode и Dcode шины разные, мультплексируются. При выборке из флеша медленого к тому же prefetch работает, размещая константы во флеше он сбросится, итого двойной тормоз выйдет.

const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.

post-5493-1514142290_thumb.png

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.
А почему глобальный конст во флеше, локальный в озу?
Изменено пользователем razrab83

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...