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

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

Локальная const переменная на стадии сборки известна.

 

 

Тогда подумайте и попробуйте собрать этот код:

 

#include <inttypes.h>
#include <stdlib.h>
#include <stdio.h>
#include <time.h>

void foo ( uint32_t in ) {
    const uint32_t test = in;
    const uint32_t *pTest = &test;

    printf ( "%d, %p\n", test, pTest );

}

int main ( void ) {
    time_t t;
    
    srand((unsigned) time(&t));

    foo ( 55 );
    foo ( 77 );

    foo ( rand() % 100 );

    return 0;
}

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


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

Тоже скажете, что константа во флеше?
Да. С точки зрения Си константа есть, а как там её компилятор реализовал - это уже дело компилятора.

 

2Quasar

const uint32_t test = in;

убедили. такая константа инитится во время выполнения. Но "const uint32_t test = 5;" инитится известна при компиляции.

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


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

2Quasar

const uint32_t test = in;

убедили. такая константа инитится во время выполнения. Но "const uint32_t test = 5;" инитится известна при компиляции.

 

Конкретно ваша "const uint32_t test = 5" соптимизируется непонятно во что. Но компилятор действует "в общем". А "в общем", модификатор const - гарант того, что конструкция "a = 5" вне блока инициализации невалидна. Остальное - следствие здравого смысла. Если можно const переменную убрать в rodata (FLASH или ro ОЗУ), её туда уберут, если нельзя - то нет, не уберут.

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


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

читаю pdf на IAR

такой забавный пример с константами:

String literals and other constants can be avoided by using initialized variables. For

example, the following lines:

__ramfunc void test()
{
/* myc: initializer in ROM */
const int myc[] = { 10, 20 };
/* string literal in ROM */
msg("Hello");
}

can be rewritten to:

__ramfunc void test()
{
/* myc: initialized by cstartup */
static int myc[] = { 10, 20 };
/* hello: initialized by cstartup */
static char hello[] = "Hello";
msg(hello);
}

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


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

Правильно, потому что это __ramfunc и никто не хочет чтоб "Hello" занимало оперативку

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


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

Если __ramfunc, то как раз все данные должны быть только в оперативке...

Например бутлоадер, который пишет во flash, не должен затрагивать данных из того-же flash.

Поэтому проще было убрать в приведённом примере слово static и слово const вовсе - результат был бы такой же, а буков меньше.

 

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


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

IAR сделан не только под миниатюрные микроконтроллеры, а документация у него общая.

приведенный выше пример справедлив, например, когда есть тормозная флешка и быстрая и большая внешняя DDR. тогда cstartup как раз скопирует константу, к которой нужен быстрый и частый доступ в DDR.

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


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

Я в свое время добавил вопрос о const в список вопросов для соискателей на собеседовании. Удивительно было то, что порой люди с опытом 5 лет и более, ничего кроме "const это константа неизменяемая" сказать не могут. А случай когда регистр периферии volatile const они обычно называют каким-то искусственным и притянутым за уши.

а он и есть приятнут за уши. Привидите плиз пример когда volatile const необходим и заоодно выдержку из стандарта где поведение этой конструкции описывается. Реально раздражают такие собеседователи с дебильными "что значит const char * const blavbla". Еще бы про auto спрашивали, который не впился ни в одно место эмеддерам ни в эпоху С, ни в эпоху С++ 14 когда он стал значить совершенно иное

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


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

Правильно, потому что это __ramfunc и никто не хочет чтоб "Hello" занимало оперативку

Упс. Не заметил, что в примере локальные статики без const. Действительно hello будет в RAM, что действительно логично для __ramfunc.

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


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

приведенный выше пример справедлив, например, когда есть тормозная флешка и быстрая и большая внешняя DDR. тогда cstartup как раз скопирует константу, к которой нужен быстрый и частый доступ в DDR.
В таких система обычно весь flash без разбора копируется в ОЗУ задолго да cstartup.

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


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

Еще бы про auto спрашивали, который не впился ни в одно место эмеддерам

 

Прошу заменять все Ваши сентенции "никому не нужен ..." на "мне не нужен".

Спасибо.

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


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

Прошу заменять все Ваши сентенции "никому не нужен ..." на "мне не нужен".

Спасибо.

хорошо, мне не нужен auto в С. Вам нужен?

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


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

Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.

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


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

Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.

Да, я про С имел в виду более. В С++ и const собственно гораздо важнее и нужнее. Просто само использование плюсов в эмбеддед ранее было сильно ограничено так сказать, свободно с STL стало писать можно относительно недавно, когда ОЗУ достаточно (256 К и более)

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


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

Привидите плиз пример когда volatile const необходим и заоодно выдержку из стандарта где поведение этой конструкции описывается.

 

Поведение volatile описано, поведение const тоже. Дерзайте, соединяйте вместе.

 

Участок одного из заголовочных файлов к STM32. Определение для __I и для __IO найдете сами. Хотя естественно можно с const не заморачиваться, также, как и с осмысленными именами функций, например.

 

Можно развить ваш вопрос: "приведите пример, когда const необходим и без него никак"?

 

typedef struct
{
  __IO uint32_t POWER;          /*!< SDIO power control register,    Address offset: 0x00 */
  __IO uint32_t CLKCR;          /*!< SDI clock control register,     Address offset: 0x04 */
  __IO uint32_t ARG;            /*!< SDIO argument register,         Address offset: 0x08 */
  __IO uint32_t CMD;            /*!< SDIO command register,          Address offset: 0x0C */
  __I uint32_t  RESPCMD;        /*!< SDIO command response register, Address offset: 0x10 */
  __I uint32_t  RESP1;          /*!< SDIO response 1 register,       Address offset: 0x14 */
  __I uint32_t  RESP2;          /*!< SDIO response 2 register,       Address offset: 0x18 */
  __I uint32_t  RESP3;          /*!< SDIO response 3 register,       Address offset: 0x1C */
... etc

} SDIO_TypeDef;

 

а он и есть приятнут за уши.

 

А какие вопросы вы считаете не притянутыми за уши для программиста встроенных систем с опытом хотя бы более 5 лет?

 

Мне всегда интересно понять, как человек думает. Даже если умный человек столкнулся первый раз с такой конструкцией (а это вполне возможно), он задумается, постарается понять, о чем речь. Неумный начнет доказывать, разбрасывая слюни в разные стороны, что оно не надо, вы все тут идиоты, так никто не программирует! Но этот человек пришел к нам, решать наши задачи за деньги. Сейчас задача понять, что значит volatile const, вот и все.

 

Бывают и совсем волшебные кандидаты, которые даже вопрос не понимают, а пишут опыт 100500 лет и более.

 

 

Не знаю, что он нынче делает в C, а в плюсах новый auto использую очень часто и нахожу очень удобным.

 

В C++ крайне нужная весчЬ.

 

Хотя в C++ я не использую это слово по старой привычке, и опираясь на логику некоторых местных товарищей, могу утверждать, что оно не нужно :-)

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


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

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

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

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

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

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

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

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

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

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