в очередной раз повторяю: квалификатор const ни о чем не говорит, кроме как о том, что переменная с этим квалификатором не должна быть модифицирована в программе. нет никаких ограничений на присваивание ее адреса указателю любого типа - хоть с явным приведением, хоть без оного. равно как и нет строгих требований, чтобы компилятор отслеживал изменение этой переменной через указатели. это если говорить о стандартном Си без извратов.
вот пример из-под AVR-GCC - компилятора, который я очень уважаю именно за достаточно скрупулезное следование стандарту Си:
как видите, есть только варнинг, ошибки нет. и это правильно, т.к. не допускает никаких иных трактовок, кроме стандартных!
Для тех кто на бронепоезде и в скафандре... На прошлой странице без const указателя и работает...
А теперь убери const с массива, а const на указателе оставь... что... скомпилировалось??? Странно... да???
"Я не даю готовых решений, я заставляю думать!"(С)
HHIMERA писал(а):У AVR-GCC const не размещает данные во флэш... насколько помню...
не размещает. И НЕ ДОЛЖЕН!
уже устал повторять: по стандарту Си квалификатор const не определяет область размещения данных в "неизменяемой" части адресного пространства! эти данные по стандарту все равно размещаются в ОЗУ!!!
то, что некоторые ушлые компиляторы для МК трактуют этот квалификатор по-своему - это проблема, а не достоинство!
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):то, что некоторые ушлые компиляторы для МК трактуют этот квалификатор по-своему - это проблема, а не достоинство!
Дык... а куда же нам бедным крестьянам деваться... юзаем что есть...
GCC под ПИК24 тоже по const данные во флэш суёт...
"Этот мир придуман не нами!"(С)
"Я не даю готовых решений, я заставляю думать!"(С)
HHIMERA писал(а):А теперь убери const с массива, а const на указателе оставь... что... скомпилировалось??? Странно... да???
Ты хотябы себя слышишь ? Не говоря уж о других...
Нахрен мне убирать const с массива, если мне нужно массив-константу и на него указатель ? Ежу понятно, что в константный указатель запишется адрес неконстантной переменной без всяких проблем.
Что ты этим хотел сказать ....
ARV писал(а):нет никаких ограничений на присваивание ее адреса указателю любого типа
Значит это "дырка", противоречащая правилам о
ARV писал(а):не должна быть модифицирована в программе
. Ибо в этом случае я спокойно смогу её модифицировать без всяких проблем.
Аlex писал(а):Значит это "дырка", противоречащая правилам. Ибо в этом случае я спокойно смогу её модифицировать без всяких проблем.
ничего подобного, это не дырка, это стандартная особенность Си.
по стандарту все const-переменные должны быть в ОЗУ, следовательно, существует 100500 способов их попортить, и это никогда ни от кого не было секретом.
но если компилятор не придерживается стандарта - возможны варианты. и это печально, т.к. делает код компиляторозависимым, сложнопереносимым, т.е. отрицает часть тех возможностей, ради которых Си и придуман.
P.S. протестируйте в своем IAR-е поведение memset или memcpy - тоже будет ругаться на первый const-указатель?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
ARV писал(а):P.S. протестируйте в своем IAR-е поведение memset или memcpy - тоже будет ругаться на первый const-указатель?
Не понял. По конкретнее можно, что сделать ?
ARV писал(а):существует 100500 способов их попортить
Ну речь идёт как бы не о "попортить", а модифицировать с помощью стандартных действий. Ну а нестандартными действиями можно попортить что угодно, не только данные в ОЗУ
Выходит, это всё таки дырка в стандарте (в коей я как-то сомневаюсь, надо погуглить на эту тему), а не способ для вандализма
стандартная библиотечная функция определена так: void *memset(void *buf, int ch, size_t count);
по стандарту тип void* совместим с любым типом указателя, поэтому должно быть можно использовать функцию и так:
ARV писал(а):что в этом случае сделает мудрый ваш IAR?
А какая разница??? const == flash ...
Мжно легко заставить работать эту хрень... ни ошибок, ни варнингов и типа всё работает... но смысл???
По командам будет видно, что прога пытается изменить значение во флэш... но ничего, естественно не изменится... что дальше???
В чём тайный смысл этих бесполезных телодвижений???
"Я не даю готовых решений, я заставляю думать!"(С)
эти простые вопросы показали, что отсутствие приверженности стандарту даже в таких простых, казалось бы, вопросах не позволяет нам однозначно понимать друг друга и код, что же говорить о более сложном?
по стандарту Си префикс const ни в коем случае не должен влиять на помещение во flash. вообще в стандарте такого нет понятия, как "память только для чтения". если AVR-GCC помещает константы в ОЗУ, IAR или ARM-GCC помещает во flash - как нам понимать код друг друга?! всякий раз изучать документацию накомпилятор собеседника?! или тупо уставившись в свой собственный компилятор, не обращать внимание на ситуацию "вовне"? а если вы переходите на другой тип МК - вы просто перелопачиваете свой код, чтобы соответствовать новым вывертам?
разве не разумнее следовать единому стандарту, чем всякий раз подстраиваться под особенности компиляторов? или сиюминутное удобство лучше? т.е. если мне удобно поворачивать налево из правого ряда - я так и буду делать, и плевать на правила? поддерживая "удобное" отступление от стандарта, мы порождаем себе проблемы...
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Процессоры и микропроцессоры разные. У кого внешнее ОЗУ, у кого флеш, у кого епром, у кого гарвардская архитектура, у кого неймановская. По этому и есть отличия в реализации компиляторов. Чего вы спорите? А..., пофлудить...
GARMIN писал(а):Процессоры и микропроцессоры разные. У кого внешнее ОЗУ, у кого флеш, у кого епром, у кого гарвардская архитектура, у кого неймановская. По этому и есть отличия в реализации компиляторов. Чего вы спорите? А..., пофлудить...
я придерживаюсь русла стандарта, и агитирую, что"стандарт - это хорошо, а отступления от него - плохо"
что касается различия в компиляторах, то в CVAVR тоже есть отличия, например, PORT.2, которое вообще никак к Си не относится (ну не определяет язык Си в качестве идентифкатора ЦИФРУ!!!). и ничего, кроме проблем с портированием кода, это "удобство" не приносит.
я за отличия компиляторов в способностях генерировать оптимальный код, но против разного толкования стандарта языка!
вот, кстати, в соседней теме та же песня - программирование PIC на Си:
Kvasshtain писал(а):Здравствуйте уважаемые Коты. Тут у меня опять не все слава богу . Я вродя разобрался с конфигурированием. Начали с товарищем воять устройство с протоколом modbus. Как известно там надо считать CRC. Заюзали табличный способ. Как полагается забили массив с атрибутом const, откомпилили, а он читается как нули. Убираешь атрибут const все хорошо. Ни кто не сталкивался с таким странным поведением компиляторов от Hi-tech? У меня возникло подозрение, что мы к этому массиву не правильно обращаемся. Ведь он при использовании атрибута const оказывается во flash-е. И я думаю, что надо это потом как то компилятору говорить. Блин, хоть ассемблерную вставляй. Главное что пиккитом проверяем флеш на наличие этого злополучного массива и он там на месте. В чем дело не пойму.
правда удобно: язык один, а программисты друг друга не понимают! у пика свой Си, у ARM-а свой Си, а у AVR - свой. очень удобно. о вавилонской башне напомнить, или и так знаете, чем там все кончилось?
если рассматривать человека снизу, покажется, что мозг у него глубоко в жопе
при взгляде на многих сверху ничего не меняется...
Это же не микрокомпьютеры, а микропроцессоры. Периферия и организация памяти - вот необходимые условия для диалектов. Мы же не пишем для сферического коня в вакууме.
Например, я пока совсем не использую new() и delete(). Не нужно.
struct pour {
uint8_t name[7];
};
struct pour pour_1L;
struct pour pour_2L;
struct pour pour_3L;
struct pour pour_1R;
struct pour pour_2R;
struct pour pour_3R;
, компилятор ругается на последнюю конструкцию словами : " useless storage class specifier in empty declaration [enabled by default]". Что это значит и как сделать правильно?
Осилит дорогу идущий
--------------------------
Пишу на Си за еду
и правильно ругается - структура только объявлена, но не существует, а вы еще добавочно объявляете.
укороченная запись, которую юзаете, без typedef, прокатила бы на с++, здесь лучше так
typedef struct {
uint8_t name[7];
}pour ; // это вынесите в заголовочный файл
struct pour pour_1L;// здесь правильно, в файл реализации
и в заголовочном экстерном, то, что нужно
extern struct pour pour_1L;