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

 
 
> Век живи, век учись..., функции в CodeVision не позволяют возвращать структуры
zhevak
сообщение Nov 17 2007, 15:00
Сообщение #1


Знающий
****

Группа: Свой
Сообщений: 723
Регистрация: 29-08-05
Из: Березовский
Пользователь №: 8 065



ну, или скорее это удар в поддых...

Ситуация такая. Пишу крупный прокт на CodeWizardAVR V1.25.3 Standard для mega2561.

Почти ООП. Почти самопальная ОСь. Сообщения, очереди, синхронизация... Проект разрастается быстро. Сегодня пришел к пониманию того, что сообщения нужно сделать не ввиде простох чисел

Код
typedef BYTE MSG;


, а как в виде структур

Код
typedef struct
{
  BYTE code;
  WORD param;
} MSG;



Предвижу Ваши соображения по поводу неизвестных BYTE и WORD. Где-то в хэдерных файлах у меня есть определение
Код
typedef unsigned char BYTE;
typedef unsigned int WORD;

так что все здесь срастается и работает.

Переделываю исходники на новый лад и ... получаю удар граблями со стороны CodeVision.
Угадайте с трех раз, откуда?

Подсказка
Цитата
Error: ... function must return a pointer to structure


раньше было красиво

msg = GetMessage();

Сейчас это уже не канает. Даже передать указатель на структуру, как это просит уважаемый CV, нельзя. Ну, не в том смысле что компилятор не пропустит, а в том, что на _какую_именно_структуру? -- Т.е. на ту, которая определяется в функции, -- нельзя. Ибо структура прекратит свое существоание в момент выхода из функции. Указатель невалиден. Значит остается, единственное решение -- наоборот, передавать указатель в функцию. Как-то это все не по-людски... sad.gif

Я уже было усомнился в своих знаниях языка (1) по передаче структур из функций, а потом в самих компиляторах для микроконтроллеров. Но нет! Ни старый добрый Borland Turbo-C 2.0, ни IAR таких ограничений не налагают.

Знаит, это есть причуда CV. Читаем в хэлпах КоудВижина

Цитата
The old Kernighan & Ritchie style of writing function definitions is not supported.


и еще тут

Цитата
Because some AVR devices have a small amount of SRAM, in order to keep the size of the Data Stack small, it is recommended not to pass structures as function parameters and use pointers for this purpose.


Правда, про возврат структур тут прямо ничего не сказано. Но видимо, подрадумевается, что программер понимает, что если передавать структуру в функцию -- это вилы, то уж возврат из функции явно крах всей системы!

Народ, не наступайте на мои грабли smile.gif Больна-а...


--------------------
Хочешь рассмешить Бога -- расскажи ему о своих планах!
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
vmp
сообщение Nov 19 2007, 06:32
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Возврат структуры - довольно неудачное решение. Где должна размещаться эта структура?
Если с простыми типами все понятно (результат передается в регистрах), то структуру (в общем случае произвольного размера) нужно размещать в памяти. Вопрос в какой? Статическая не подойдет (имеем проблемы с рекурсией и прерываниями), остается динамическая, т.е. стек или куча. Т.е. компилятор на входе в функцию должен создать данную структуру, на выходе из функции заполнить ее (скорее всего скопировав содержимое из локальной структуры). Вызывающая функция должна скопировать результат куда-то ещё и не забыть уничтожить временное хранилище.
И оно надо в микроконтроллерной программе? Двойной расход памяти и двойное копирование? Так что либо вообще не использовать структуры для возврата, либо просто передавать указатель в явном виде (всё равно будет оптимальнее).
Go to the top of the page
 
+Quote Post
dxp
сообщение Nov 19 2007, 06:38
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(vmp @ Nov 19 2007, 12:32) *
Возврат структуры - довольно неудачное решение. Где должна размещаться эта структура?
Если с простыми типами все понятно (результат передается в регистрах), то структуру (в общем случае произвольного размера) нужно размещать в памяти. Вопрос в какой? Статическая не подойдет (имеем проблемы с рекурсией и прерываниями), остается динамическая, т.е. стек или куча. Т.е. компилятор на входе в функцию должен создать данную структуру, на выходе из функции заполнить ее (скорее всего скопировав содержимое из локальной структуры). Вызывающая функция должна скопировать результат куда-то ещё и не забыть уничтожить временное хранилище.
И оно надо в микроконтроллерной программе? Двойной расход памяти и двойное копирование? Так что либо вообще не использовать структуры для возврата, либо просто передавать указатель в явном виде (всё равно будет оптимальнее).

Почему ж так все драматично? Компилятор вполне сам может передать неявный указатель и внутри функции сразу работать с той памятью, где расположена структура (например, в стеке вызывающей функции). Никакого дополнительного копирования и проблем с аллокацией дополнительной памяти тут нет. Приличные компиляторы так и делают. Получается очень эффективно. Пользователю на это заморачиваться не нужно.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
vmp
сообщение Nov 19 2007, 08:03
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 426
Регистрация: 20-01-05
Из: Зеленоград
Пользователь №: 2 070



Цитата(dxp @ Nov 19 2007, 09:38) *
Никакого дополнительного копирования и проблем с аллокацией дополнительной памяти тут нет.


Разве?
Итак, чтобы использовать структуру в качестве результата функции, нам в общем случае нужны 3 структуры:
1. Локальная в вызываемой функции. Она заполняется этой функцией и затем её имя используется в операторе return;
2. Неявная переменная на стеке, в которой и будет возвращен результат.
3. Локальная или глобальная переменная в вызывающей функции, которой будет присвоен результат вызова.

Разместить все 3 переменные по одному адресу можно только при очень удачном стечении обстоятельств. При запуске простейшего тестового примера на IAR EWARM 4.41A этого не получилось - компилятор совместил только переменные 1 и 2, достигнув всего лишь двойного, а не тройного расхода памяти. Оптимизация -s9.
Go to the top of the page
 
+Quote Post
Непомнящий Евген...
сообщение Nov 19 2007, 08:43
Сообщение #5


Знающий
****

Группа: Свой
Сообщений: 771
Регистрация: 16-07-07
Из: Волгодонск
Пользователь №: 29 153



Цитата(vmp @ Nov 19 2007, 11:03) *
Разве?


Main.cpp:
Код
struct TTest
{
    int a[100];
};

TTest func();

TTest t;

void main()
{
t = func();
}


func.cpp
Код
struct TTest
{
    int a[100];
};

TTest func()
{
    TTest t;
    t.a[10] = 100;
    return t;
}


После компиляции:
для main имею:
Код
151              t = func();
   \   0000000A   ....               LDI     R16, LOW(t)
   \   0000000C   ....               LDI     R17, (t) >> 8
   \   0000000E   ........           CALL    ??func

для func.cpp
Код
30          TTest func()
   \                     ??func:
    131          {
   \   00000000   97EF               SBIW    R29:R28, 63
   \   00000002   97EF               SBIW    R29:R28, 63
   \   00000004   97EF               SBIW    R29:R28, 63
   \   00000006   972B               SBIW    R29:R28, 11
   \   00000008   01B8               MOVW    R23:R22, R17:R16
    132              TTest t;
    133              t.a[10] = 100;
   \   0000000A   E604               LDI     R16, 100
   \   0000000C   E010               LDI     R17, 0
   \   0000000E   8B0C               STD     Y+20, R16
   \   00000010   8B1D               STD     Y+21, R17
    134              return t;
   \   00000012   018B               MOVW    R17:R16, R23:R22
   \   00000014   01FE               MOVW    R31:R30, R29:R28
   \   00000016   EC48               LDI     R20, 200
   \   00000018   E050               LDI     R21, 0
   \   0000001A   ........           CALL    ?ML_SRAM_SRAM_16_L07
   \   0000001E   96EF               ADIW    R29:R28, 63
   \   00000020   96EF               ADIW    R29:R28, 63
   \   00000022   96EF               ADIW    R29:R28, 63
   \   00000024   962B               ADIW    R29:R28, 11
   \   00000026   9508               RET
    135          }


Если же TTest - небольшая, то получится что-то вроде:
Код
130          TTest func()
   \                     ??func:
    131          {
    132              TTest t = {0};
   \   00000000   ....               LDI     R30, LOW(`?<Constant {{0}}>`)
   \   00000002   ....               LDI     R31, HIGH(`?<Constant {{0}}>`)
   \   00000004   ....               LDI     R19, (`?<Constant {{0}}>`) >> 16
   \   00000006   BF3B               OUT     0x3B, R19
   \   00000008   9147               ELPM    R20, Z+
   \   0000000A   9157               ELPM    R21, Z+
    133              t.a[1] = 100;
    134              return t;
   \   0000000C   018A               MOVW    R17:R16, R21:R20
   \   0000000E   E624               LDI     R18, 100
   \   00000010   E030               LDI     R19, 0
   \   00000012   9508               RET
    135          }


Т.е., небольшие структуры возвращаются через регистры, большие - через неявный указатель.
Никакого дополнительного расхода памяти...

И помоему нет ни одной разумной причины не реализовать возврат структур в компиляторе, если это есть в стандарте языка.

У меня IAR 4.30
Go to the top of the page
 
+Quote Post

Сообщений в этой теме
- zhevak   Век живи, век учись...   Nov 17 2007, 15:00
- - Yason   Цитата(zhevak @ Nov 17 2007, 16:00) Значи...   Nov 17 2007, 15:16
- - Сергей Борщ   Цитата(zhevak @ Nov 17 2007, 17:00) ну, и...   Nov 17 2007, 15:27
|- - zhevak   Цитата(Yason @ Nov 17 2007, 20:16) Прошу ...   Nov 17 2007, 16:54
|- - VDG   ЦитатаРазница между МС и моим ГетМессэйджем в том,...   Nov 17 2007, 22:46
- - VDG   Я что-то не въезжаю. ЦитатаИбо структура прекратит...   Nov 17 2007, 16:08
|- - WHALE   Цитата(VDG @ Nov 17 2007, 19:08) Я что-то...   Nov 17 2007, 16:29
|- - zhevak   Цитата(VDG @ Nov 17 2007, 21:08) Я что-то...   Nov 17 2007, 18:03
- - WHALE   ну и при чем здесь CV?Если вам надо ООП,пространст...   Nov 17 2007, 17:08
|- - zhevak   Цитата(WHALE @ Nov 17 2007, 22:08) ну и п...   Nov 17 2007, 17:24
|- - Сергей Борщ   Цитата(WHALE @ Nov 17 2007, 19:08) Паша Х...   Nov 17 2007, 17:32
|- - ReAl   Цитата(WHALE @ Nov 17 2007, 19:08) почему...   Nov 17 2007, 21:35
- - SlavaG   Можно попробовать сделать так: Кодtypedef union {...   Nov 17 2007, 18:30
|- - zhevak   Цитата(SlavaG @ Nov 17 2007, 23:30) Можно...   Nov 17 2007, 19:21
||- - zhevak   Цитата(vmp @ Nov 19 2007, 13:03) Итак, чт...   Nov 19 2007, 08:50
||- - dxp   Цитата(zhevak @ Nov 19 2007, 14:50) Я про...   Nov 19 2007, 09:17
||- - zhevak   Цитата(dxp @ Nov 19 2007, 14:17) А где ту...   Nov 19 2007, 09:39
||- - dxp   Цитата(zhevak @ Nov 19 2007, 15:39) Прозр...   Nov 19 2007, 10:06
||- - defunct   Цитата(zhevak @ Nov 19 2007, 12:39) Прозр...   Nov 19 2007, 10:49
|- - IgorKossak   Цитата(vmp @ Nov 19 2007, 08:32) Возврат ...   Nov 19 2007, 07:43
- - zhevak   я там где-то ранее обещал опубликовать результаты ...   Nov 21 2007, 20:18
- - VDG   12-ти %-ная разница в объёме сгенерировнного кода....   Nov 21 2007, 23:02


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

 


RSS Текстовая версия Сейчас: 21st July 2025 - 13:34
Рейтинг@Mail.ru


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