inventor 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба где компилятор должен расположить "переменные" такого вида: // Описано глобально 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 память. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба rtfm, очень нужно почитать умную книжку по языку на котором разрабатываете. Модификатор const = сообщение компилятору что бы он проследил что бы код в котором определена эта переменная не пытался менять эти данные. Никаких других гарантий просто const не даёт. А еще бывают такие случаи как например volatile const или const register или const - аргумент функции или преобразования типов при которых cv-модификаторы меняются. Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно. Всё увиденное - верное поведение. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба Вместе с тем конкретные компиляторы и линкеры для ембеда размещают глобальные константы во флеше. Как они станут глобальными через объявление на верхнем уровне или через спецификатор static - не важно. Всё увиденное - верное поведение. может ли компилятор поместить static const не во flash а в памяти данных? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба может ли компилятор поместить static const не во flash а в памяти данных? Легко. Причём это поведение описано в стандарте. Если у флэша и ОЗУ разные адресные пространства именно так и будет. Например, для AVR специально придуман квалификатор __flash, который укажет компилятору, что данные нужно поместить во флэш, а не в основную память (коей считается ОЗУ). Для ARM, где единое адресное пространство, можно с уверенностью сказать, что static const данные лягут во флэш (кроме случая когда компилятор решит соптимизировать) . Умная книга, которую ТС советовали читать - это стандарт языка Си... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Raven 11 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH) Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба Нет не должен т.к. .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 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба может ли компилятор поместить static const не во flash а в памяти данных? Теоретически может, но делать этого не будет, т.к. поведение задано настройками. Если говорить за gcc, то где-то в недрах проекта у вас должен быть файл с расширением *.ld в котором записано что и куда класть. Вы можете его редактировать что бы получить результат отличный от того того что по умолчанию. А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH) А линкер может в соответствии со своим скриптом секцию запихнуть туда куда записано в скрипте. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
demiurg_spb 0 22 декабря, 2017 Опубликовано 22 декабря, 2017 · Жалоба Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё. А куда они лягут - об этом более нет ни слова. Кстати, задумайтесь над тем что будет если константные данные всегда будут лежать во флэш и чем это чревато для архитектуры 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; Это я к чему - крутить параметры в скриптах линкера надо не с шашой наголо, а очень и очень вдумчиво... Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
k155la3 27 23 декабря, 2017 Опубликовано 23 декабря, 2017 · Жалоба А разве не должен компилятор помещать глобальные и static const объекты в .rodata секцию? (которая естественным образом ассоциируется с FLASH) Я сразу себя приучил, что компилятор мне ничего не "должен" :) Особенно в части, если включена оптимизация. И даже если не включена. Есть много платформо-зависимых ньюансов. Разобраться, опятьже, помогает RTFM + работа в отладчике с memory-->View. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
inventor 0 23 декабря, 2017 Опубликовано 23 декабря, 2017 · Жалоба то есть для того что бы константные данные легли во flash память необходимо сделать typedef для такого типа: typedef const unsigned char cu8; #define scu8 static cu8 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
Kabdim 0 23 декабря, 2017 Опубликовано 23 декабря, 2017 · Жалоба Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё. Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 23 декабря, 2017 Опубликовано 23 декабря, 2017 · Жалоба Верно, но пост был про поведение компилятора, а раздел для новичков, так что ответ по дефолту шел про армы о чем свидетельствуют некоторые ответы ТСа. Об особенностях авров честно говоря задумываться не хочу, в 2017 труп уже пора закопать. ну да, stm8 дешевле. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
juvf 17 24 декабря, 2017 Опубликовано 24 декабря, 2017 · Жалоба Согласно стандарту языка Си константные данные обязаны лечь в основное адресное пространство - всё.Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство. ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры. Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ? Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
DASM 0 24 декабря, 2017 Опубликовано 24 декабря, 2017 · Жалоба Что такое "основное адресное пространство"? В Си нет такого. В Си нет адресных пространств одно адресное пространство. ps и в вашем авр нет основного адр. простр. В авр гарвардская архитектура, там есть адресное пространство памяти программ и адресное пространство памяти данных. Но к стандарту Си это отношения не имеет, т.к. Си абстрагирован от архитектуры. Куда разместит - зависит от компилятора. А вообще мне тоже не понятно почему во 2-м случае в ОЗУ. Получается что эти данный размещены дважды - и в озу и в пзу. Если это авр - то это понятно, для авр все случаи должны быть в озу. Если арм - то вроде как все константы должны быть в флеше. Зачем их дублировать в ОЗУ? хотя бы потому, что ICode и Dcode шины разные, мультплексируются. При выборке из флеша медленого к тому же prefetch работает, размещая константы во флеше он сбросится, итого двойной тормоз выйдет. const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать. Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться
razrab83 21 25 декабря, 2017 Опубликовано 25 декабря, 2017 (изменено) · Жалоба const нужен только чтобы уберечь программиста от самого себя, а никак не указание компилятору что и как размещать.А почему глобальный конст во флеше, локальный в озу? Изменено 25 декабря, 2017 пользователем razrab83 Цитата Поделиться сообщением Ссылка на сообщение Поделиться на другие сайты Поделиться