Оберон-клуб «ВЄДАsoft» https://zx.oberon.org/forum/ |
|
Ошибка SDCC присваивания записи целиком https://zx.oberon.org/forum/viewtopic.php?f=10&t=264 |
Страница 1 из 3 |
Автор: | Saferoll [ 09 янв 2016, 19:30 ] |
Заголовок сообщения: | Ошибка SDCC присваивания записи целиком |
SDCC до сих пор не понимает оператор присваивания для всей записи целиком (проблема Feature cannot assign values to aggregates). Один из возможных способов исправления - заставить Ofront генерировать для записей не оператор присваивания "a=b;" , а вызов макроса __COPYREC(a,b,size). Для этого в модуле OPV нужно исправить в процедуре stat обработку узла assign: Код: "OBERON"
Код: "OBERON"
транслируется в Код: "C" __COPYREC( AsgnRec_a, AsgnRec_b, sizeof(AsgnRec_Card)); Необходимо добавить в файл ZXDev\Lib\C\SYSTEM.h макроопределение: Код: "C" #define __COPYREC(d, s, n) memcpy((char*)(d),(char*)(s),n) |
Автор: | Saferoll [ 09 янв 2016, 19:47 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Просто переменных-записей всё работает, но возникает проблема для указателей на записи: Код: "OBERON"
При операциях с указателями генерируется охрана типов через макросы ZXDev\Lib\C\SYSTEM.h: Код: "C" #define __GUARDEQR(p, dyntyp, typ) if(dyntyp!=typ##__typ) __HALT(-6);*(p) Выход состоит в замене макросов на выражения с тернарным "? :" : Код: "C" #define __GUARDEQR(p, dyntyp, typ) *((dyntyp!=typ##__typ)?__HALT(-6):p) Вместе с исправлением __HALT это решает проблему. Правда замена конструкции if на тернарный оператор в данном случае немного снижает эффективность. Возможно, для Спектрума вообще следует отключить подобные проверки указателей (особенно для динамической типизации). |
Автор: | Zorko [ 10 янв 2016, 00:24 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Saferoll писал(а): SDCC до сих пор не понимает оператор присваивания для всей записи целиком. Олежек, а я с этим боролся вот как:Код: "OBERON"
Согласен, это не слишком удобно. Так что твоё предложение одобряю. |
Автор: | Zorko [ 13 янв 2016, 03:55 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Предлагаю вместо sizeof(type) подставлять сразу числовое значение. Это несложно. В OPV.stat вместо: Код: "OBERON"
Код: "OBERON"
Saferoll писал(а): Возможно, для Спектрума вообще следует отключить подобные проверки указателей (особенно для динамической типизации). Безусловно. Это регулируется опцией OPM.typchk, могу сделать директиву (*$TYPCHK-*) для вставки в исходник.Поразмыслил над тем, не генерировать ли вместо: Код: "C" __COPYREC(__GUARDEQP(AsgnRec2_p, AsgnRec2_Card), AsgnRec2_a, 4); Код: "C" __GUARDEQP(AsgnRec2_p, AsgnRec2_Card); __COPYREC(AsgnRec2_p, AsgnRec2_a, 4); |
Автор: | Saferoll [ 17 янв 2016, 09:01 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Zorko писал(а): Предлагаю вместо sizeof(type) подставлять сразу числовое значение. Это несложно. В OPV.stat вместо: Да, лучше подставлять сразу число. Код: "OBERON"
Код: "OBERON"
Кстати, а что будет при динамической типизации, будет ли там указываться верный размер? И возможна ли, вообще, динамическая типизация для данной версии? Zorko писал(а): Поразмыслил над тем, не генерировать ли вместо: Отделение проверки даст несколько более эффективный код, но... 1)указатели могут быть не только на записи 2)при прямом присваивании записей не делается проверка. И я не знаю точно, делается ли проверка __GUARDEQP только для присваивания, или используется для аргументов других операций.Код: "C" __COPYREC(__GUARDEQP(AsgnRec2_p, AsgnRec2_Card), AsgnRec2_a, 4); Код: "C" __GUARDEQP(AsgnRec2_p, AsgnRec2_Card); __COPYREC(AsgnRec2_p, AsgnRec2_a, 4); Так что вынести проверку отдельно не так-то просто. |
Автор: | Zorko [ 17 янв 2016, 18:03 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Saferoll писал(а): Кстати, а что будет при динамической типизации, будет ли там указываться верный размер? Да, ведь размер динамических типов точно известен в момент компиляции.Saferoll писал(а): И возможна ли, вообще, динамическая типизация для данной версии? Конечно же, Олежек. И даже динамическая модульность каким-то образом возможна. Я, правда, не тестировал, но в спеке на Ofront всё это заявлено. Если мы ещё не успели сломать. ![]() Saferoll писал(а): Так что вынести проверку отдельно не так-то просто. Абсолютно согласен. А как ты смотришь на то, чтобы добавить опцию "SDCC support"?
|
Автор: | Saferoll [ 18 янв 2016, 20:20 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Zorko писал(а): А как ты смотришь на то, чтобы добавить опцию "SDCC support"? А что именно будет делать эта опция?
|
Автор: | Zorko [ 19 янв 2016, 02:18 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Включать __COPYREC вместо rec1=rec2 ![]() |
Автор: | Saferoll [ 21 янв 2016, 18:01 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
Zorko писал(а): Включать __COPYREC вместо rec1=rec2 ![]() Да, нужно такое сделать. Возможно, это пригодится не только для присвоения записей. |
Автор: | enemy [ 25 янв 2016, 07:05 ] |
Заголовок сообщения: | Re: Ошибка SDCC присваивания записи целиком |
>>> Например, можно было бы сделать спектрумную реализацию макроса __COPYREC не через memcpy (вызов подпрограммы), а прямо LD DE,AsgnRec2_p : LD HL,AsgnRec2_a : LD BC,4 : LDIR. так SDCC так и делает, вместо memcpy вставляет Код: "OBERON"
Код: "OBERON"
|
Страница 1 из 3 | Часовой пояс: UTC + 2 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |