|
Си: 2 константы-структуры с полями-указателями друг на друга, как объяснить компилятору? |
|
|
|
Feb 29 2012, 23:22
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Собственно, сабжевая задача. Обходные варианты есть, но хочется красиво  Структура. Одно из полей - указатель на структуру этого же типа. 2 переменные. Одна содержит в этом поле указатель на вторую, вторая - на первую. Если не константы - то все работает, ибо мы присваиваем значение полям когда угодно. Если константы - не работает, ибо надо при определении заполнить её значениями, а вторая переменная получается ещё не определена и не получается на неё указать  ЗЫ сейчас пробую разнести на 2 файла и поиграться экстернами, но пока не получается  Вроде удалось добиться понимания от компилятора в результате следующих искусственных манипуляций: делается хедэр с определением типа Код 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}; Билд проекта собирается. ошибок не выдает. Теперь попозже проверю как это работает в реале
Сообщение отредактировал _Ivana - Feb 29 2012, 23:23
|
|
|
|
|
Mar 1 2012, 05:54
|

Частый гость
 
Группа: Свой
Сообщений: 103
Регистрация: 17-05-09
Из: Ижевск
Пользователь №: 49 190

|
А если попробовать сделать члены структуры константами, а саму структуру переменной. Создать по объекту класса, а потом инициализировать констатнтый указатель (звучит как бред, однако Студия 2005 не ругнулась  ) Просто боюсь, что вылезут вилы при выполнений кода, по-скольку вы пытаетесь создать ссылку на еще не существующий объект...
--------------------
Шизоидный холерик
|
|
|
|
|
Mar 1 2012, 07:19
|

Частый гость
 
Группа: Свой
Сообщений: 103
Регистрация: 17-05-09
Из: Ижевск
Пользователь №: 49 190

|
Цитата(_Ivana @ Mar 1 2012, 11:46)  все поля константы а она сама не константа? В ОЗУ или флэш? А если половина полей константы? Не пробовал ещё так исхитряться  Да идея беспонтовая на самом деле)) А на счет куда поместит = WinAvr - помещает во флеш и копирует в ОЗУ, как и с любой переменной со спецификатором типа const. А для чего константный указатель?
Сообщение отредактировал Marto - Mar 1 2012, 07:24
--------------------
Шизоидный холерик
|
|
|
|
|
Mar 1 2012, 07:35
|

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

|
QUOTE (_Ivana @ Mar 1 2012, 01:22)  делается 2 файла, в которые инклюдится этот хедэр и пишется в одном Можно то же самое сделать и в одном файле CODE typedef struct our { unsigned char c; struct our const *s_our; } our_struct;
extern our_struct const s1; const our_struct s2 = {'A', &s1}; const our_struct s1 = {'A', &s2}; Объявление типа, при необходимости, можно вынести в заголовочный файл.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 1 2012, 09:19
|

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

|
QUOTE (Marto @ Mar 1 2012, 11:01)  Сами пробовали компилить? Да. CODE D:\Projects\test\uuu>make avr-gcc --version avr-gcc.exe (WinAVR 20100110) 4.3.3 Copyright (C) 2008 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
cat test.c typedef struct our { unsigned char c; struct our const *s_our; } our_struct;
extern our_struct const s1; const our_struct s2 = {'A', &s1}; const our_struct s1 = {'A', &s2};
int main() { for(;;) ; } Compiling: test.c avr-gcc -mmcu=atmega8 -Wall -gdwarf-2 -DF_CPU=14745000UL -Os -fsigned-char -funsigned-bitfields -fshort-enums -MD -MP -MT ./release/obj/test.o -MF ./release/dep/test.o.d -ffunction-sections -fdata-sections -fno-ivopts --param inline-call-cost=0 -fno-move-loop-invariants -Wa,-ahlmsd=./release/lst/test.lst -c test.c -o release/obj/test.o Linking: release/struct_test.elf avr-gcc -mmcu=atmega8 -Wl,-Map=./release/lst/struct_test.map -Wl,--gc-sections -Wl,--relax ./release/obj/test.o -o release/struct_test.elf Generating hex: release/struct_test.hex avr-objcopy -O ihex -R .eeprom release/struct_test.elf release/struct_test.hex Generating eep: release/struct_test.ee.hex avr-objcopy -O ihex -j .eeprom --set-section-flags=.eeprom="alloc,load" --change-section-lma .eeprom=0 --no-change-warnings release/struct_test.elf release/struct_test.ee.hex || exit 0 Generating disassembly: release/lst/struct_test.lss avr-objdump -h -S release/struct_test.elf > release/lst/struct_test.lss AVR Memory Usage ---------------- Device: atmega8
Program: 84 bytes (1.0% Full) (.text + .data + .bootloader)
Data: 0 bytes (0.0% Full) (.data + .bss + .noinit) Еще вопросы?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Mar 1 2012, 12:02
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Сергей Борщ блин, посыпАю голову пеплом! Стыдно  Просто эта задача и идея не моя, вчера (сегодня  ) в 3 ночи мне в аську написал товарищ и попросил помочь с этой задачкой - типа очень надо, код разбора-прыгания по структурам получается очень красивый, но вот с константами не работает - как он ни бился!  Он меня заверил, что он перепробовал в одном файле все варианты определений и задания начальных значений, в том числе и экстерны, но не смог решить "проблему курицы и яйца"! А поскольку он гораздо опытнее меня в программировании МК на Си, то я просто тупо поверил ему и решил исхитриться, но не удосужился проверить очевидное. Скопипастил ваш вариант в тестовый проект, все компилится и билдится без ошибок
|
|
|
|
|
Mar 1 2012, 15:38
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Казалось бы, все понятно и тема закрыта  Это так, но лично меня интересует ещё полтора нюанса: 0.5) в объявленииКод extern our_struct const s1; порядок указания типа и директивы "const" не имеет значения? Вроде проверил и так и так, работают оба варианта. 1) в том же объявлении у меня в варианте 2-х файлов вообще нет директивы "const". Проверил без этой директивы в варианте от Сергей Борщ - тоже работает. На такие мысли меня натолкнули Керриган с Риччи - написано, что объявление говорит о том, что переменная обладает определенными свойствами (в основном типом), а при определении выделяется для нее место в памяти. Если это так, тогда в объявлении можно не указывать "const", поскольку это относится к выделению места в памяти.
|
|
|
|
|
Mar 1 2012, 16:18
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Пока согласно моим заблуждениям, в объявлении это не означает ничего  А в определении - да, область размещения (ОЗУ или флэш). Про параметры функции - имхо они и так передаются по значению а не по ссылке и значит не меняются.
|
|
|
|
|
Mar 1 2012, 16:45
|

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

|
Цитата(_Ivana @ Mar 1 2012, 20:18)  Пока согласно моим заблуждениям, в объявлении это не означает ничего а разве при объявлении мы не говорим, где расположится переменная? upd никогда не заморачивался, но проверил... const переменная должна определяться там же, где и объявляется
|
|
|
|
|
Mar 1 2012, 16:56
|
Местный
  
Группа: Свой
Сообщений: 352
Регистрация: 13-08-11
Из: Воронеж
Пользователь №: 66 710

|
Мне кажется что объявление - чистая надстройка Си, нужная компилятору только для того чтобы узнать какой тип у переменной. ЗЫ а я убрал "const" из объявления и никаких ошибок при компилировании/билде. Могу проверить в железе, но не скоро. Может ещё быть такое, что разные компиляторы по-разному на это дело реагируют, но мне мои заблуждения кажутся логичными и обоснованными
Сообщение отредактировал _Ivana - Mar 1 2012, 16:59
Эскизы прикрепленных изображений
|
|
|
|
2 чел. читают эту тему (гостей: 2, скрытых пользователей: 0)
Пользователей: 0
|
|
|