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

 
 
> Си: 2 константы-структуры с полями-указателями друг на друга, как объяснить компилятору?
_Ivana
сообщение Feb 29 2012, 23:22
Сообщение #1


Местный
***

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



Собственно, сабжевая задача. Обходные варианты есть, но хочется красиво sm.gif
Структура. Одно из полей - указатель на структуру этого же типа.
2 переменные. Одна содержит в этом поле указатель на вторую, вторая - на первую. Если не константы - то все работает, ибо мы присваиваем значение полям когда угодно.
Если константы - не работает, ибо надо при определении заполнить её значениями, а вторая переменная получается ещё не определена и не получается на неё указать sm.gif

ЗЫ сейчас пробую разнести на 2 файла и поиграться экстернами, но пока не получается sm.gif

Вроде удалось добиться понимания от компилятора в результате следующих искусственных манипуляций:

делается хедэр с определением типа
Код
typedef struct our
{
    unsigned char c;
    struct our *s_our;
} our_struct;


делается 2 файла, в которые инклюдится этот хедэр и пишется в одном
Код
extern our_struct s1;
const our_struct s2 = {'A', &s1};


и в другом
Код
extern our_struct s2;
const our_struct s1 = {'A', &s2};


Билд проекта собирается. ошибок не выдает. Теперь попозже проверю как это работает в реале sm.gif

Сообщение отредактировал _Ivana - Feb 29 2012, 23:23
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Ivana
сообщение Mar 1 2012, 15:38
Сообщение #2


Местный
***

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



Казалось бы, все понятно и тема закрыта sm.gif Это так, но лично меня интересует ещё полтора нюанса:

0.5) в объявлении
Код
extern our_struct const s1;

порядок указания типа и директивы "const" не имеет значения? Вроде проверил и так и так, работают оба варианта.

1) в том же объявлении у меня в варианте 2-х файлов вообще нет директивы "const". Проверил без этой директивы в варианте от Сергей Борщ - тоже работает.

На такие мысли меня натолкнули Керриган с Риччи - написано, что объявление говорит о том, что переменная обладает определенными свойствами (в основном типом), а при определении выделяется для нее место в памяти. Если это так, тогда в объявлении можно не указывать "const", поскольку это относится к выделению места в памяти.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Mar 1 2012, 17:57
Сообщение #3


Гуру
******

Группа: Модераторы
Сообщений: 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   Си: 2 константы-структуры с полями-указателями друг на друга   Feb 29 2012, 23:22
- - Marto   А если попробовать сделать члены структуры констан...   Mar 1 2012, 05:54
- - _Ivana   Спасибо за идею, вечером попробую. Только всвязи с...   Mar 1 2012, 06:46
|- - Marto   Цитата(_Ivana @ Mar 1 2012, 11:46) все по...   Mar 1 2012, 07:19
- - Сергей Борщ   QUOTE (_Ivana @ Mar 1 2012, 01:22) делает...   Mar 1 2012, 07:35
- - Marto   Сами пробовали компилить?   Mar 1 2012, 09:01
|- - Сергей Борщ   QUOTE (Marto @ Mar 1 2012, 11:01) Сами пр...   Mar 1 2012, 09:19
- - Marto   Вопросов нет. Нашел ошибку у себя. Спасибо.   Mar 1 2012, 09:55
- - _Ivana   Сергей Борщ блин, посыпАю голову пеплом! Стыдн...   Mar 1 2012, 12:02
|- - toweroff   Цитата(_Ivana @ Mar 1 2012, 19:38) Если э...   Mar 1 2012, 16:13
- - _Ivana   Пока согласно моим заблуждениям, в объявлении это ...   Mar 1 2012, 16:18
|- - toweroff   Цитата(_Ivana @ Mar 1 2012, 20:18) Пока с...   Mar 1 2012, 16:45
- - _Ivana   Мне кажется что объявление - чистая надстройка Си,...   Mar 1 2012, 16:56
- - toweroff   Вопрос. Мы говорим о расширении языка для MC?   Mar 1 2012, 17:03
- - _Ivana   Цитатаupd никогда не заморачивался, но проверил......   Mar 1 2012, 17:05
- - toweroff   Цитата(_Ivana @ Mar 1 2012, 20:56) ЗЫ а я...   Mar 1 2012, 17:07
- - _Ivana   Сергей Борщ очередное спасибо за грамотное и детал...   Mar 1 2012, 18:11


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

 


RSS Текстовая версия Сейчас: 19th July 2025 - 17:36
Рейтинг@Mail.ru


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