реклама на сайте
подробности

 
 
2 страниц V  < 1 2  
Reply to this topicStart new topic
> Си: 2 константы-структуры с полями-указателями друг на друга, как объяснить компилятору?
_Ivana
сообщение Mar 1 2012, 17:05
Сообщение #16


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Цитата
upd
никогда не заморачивался, но проверил...

const переменная должна определяться там же, где и объявляется

Не понял как вы это проверили. И почему тогда мой пример в самом первом посте не дает ошибок?
Go to the top of the page
 
+Quote Post
toweroff
сообщение Mar 1 2012, 17:07
Сообщение #17


Гуру
******

Группа: Свой
Сообщений: 2 957
Регистрация: 19-09-06
Из: Москва
Пользователь №: 20 514



Цитата(_Ivana @ Mar 1 2012, 20:56) *
ЗЫ а я убрал "const" из объявления и никаких ошибок при компилировании/билде

конечно!
компилятор разместил их в ОЗУ

Цитата(_Ivana @ Mar 1 2012, 21:05) *
Не понял как вы это проверили

то есть?
оставил объявление константной переменной (во флеш), а попытался проинициализировать ее в main
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 1 2012, 17:57
Сообщение #18


Гуру
******

Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095



QUOTE (_Ivana @ Mar 1 2012, 17:38) *
0.5) в объявлении
CODE
extern our_struct const s1;

порядок указания типа и директивы "const" не имеет значения? Вроде проверил и так и так, работают оба варианта.
Да, не имеют.
Однако обратите внимание, что char const * Variable; char * const Variable; и char const * const Variable; - три объявления совершенно разных указателей. Аналогично с квалификатором volatile и квалификаторами адресных пространств (если они имеются в качестве расширения языка) наподобие __flash, __eeprom.
QUOTE (_Ivana @ Mar 1 2012, 17:38) *
1) в том же объявлении у меня в варианте 2-х файлов вообще нет директивы "const". Проверил без этой директивы в варианте от Сергей Борщ - тоже работает.

Если у вас нет const ни в строке extern our_struct s1; ни в строке const our_struct s1 = {'A', &s2}; - тоже все нормально. Если только в первой - по идее должна быть ошибка. Ведь вы обманули компилятор - вы сказали, что в s1 можно писать, а потом объявили ее константной. Опять же, если вы уберете const у struct our const *s_our; - вы не сможете присвоить этому полю адрес константной s2 или s1. Похоже именно на это и наткнулся ваш товарищ. В Си существует правило неявного приведения типов - указателю на константную переменную можно присвоить адрес неконстантного объекта (этим вы лишь ограничиваете операции доступа к такой переменной операциями чтения), но указателю на неконстантную переменную нельзя присвоить адрес константной переменной - тем самым вы разрешали бы через этот указатель операции записи в константную переменную, а это уже жульничество, для него существуют явные приведения типа, которые надо использовать тогда и лишь только тогда, когда такое жульничество необходимо и осознанно.

QUOTE (_Ivana @ Mar 1 2012, 17:38) *
На такие мысли меня натолкнули Керриган с Риччи - написано, что объявление говорит о том, что переменная обладает определенными свойствами (в основном типом),
Да, совершенно верно. И свойство"нельзя писать" - такое же неотъемлемое, как и размер, тип или знаковость. Ведь компилятор должен на основе этого объявления проверять ваши обращения к этой переменной и использовать (где необходимо) правиля неявного приведения типов.

QUOTE (_Ivana @ Mar 1 2012, 17:38) *
а при определении выделяется для нее место в памяти. Если это так, тогда в объявлении можно не указывать "const", поскольку это относится к выделению места в памяти.
Вы глубоко ошибаетесь. В вашей писюге все программы, включая константы и исполняемый код, целиком размещаются в ОЗУ. И const на это повлиять не может при всем желании. Сам по себе квалификатор const никакой магии не несет - он лишь заставляет компилятор проверять, не пытаетесь ли вы записать в такую переменную. То, что для некоторых процессоров такую переменную можно разместить во флешь и не копировать перед исполнением в ОЗУ, реализуется исключительно средствами линкера. Компилятор об этом совершенно ничего не знает.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
_Ivana
сообщение Mar 1 2012, 18:11
Сообщение #19


Местный
***

Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710



Сергей Борщ очередное спасибо за грамотное и детальное объяснение (возможно для многих давно очевидных) вещей! И сорри за глупые вопросы - просто хочется сформировать в голове четкое представление-абстракцию: как же это все на самом деле работает sm.gif
Go to the top of the page
 
+Quote Post

2 страниц V  < 1 2
Reply to this topicStart new topic
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0

 


RSS Текстовая версия Сейчас: 23rd August 2025 - 18:55
Рейтинг@Mail.ru


Страница сгенерированна за 0.01611 секунд с 7
ELECTRONIX ©2004-2016