|
WinAVR и адрес статической функции, странная ошибка |
|
|
|
Jun 6 2011, 09:45
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Код static basis sum(uint8_t arg_cnt, void **args){ basis result = 0; for(;arg_cnt--;*args++){ result += evalute(args); } return result; }
#define num(x) ((x) & 0xFF), (((x) >> 8) & 0xFF), (((x) >> 16UL) & 0xFF), (((x) >> 24UL) & 0xFF)
#define adr(x) ((uint16_t)(x) & 0xFF), ((uint16_t)(x) & 0xFF00) >> 8 uint8_t massiv[] = { TOC_VAR, 0, TOC_FUNC,adr(sum), 0, 3, TOC_NUMBER, num(99UL), TOC_NUMBER, num(1UL), TOC_VAR, 0, TOC_END }; не получается занести в массив адрес функции  пишет - не константа  с чего бы это вдруг?
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jun 7 2011, 04:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(zltigo @ Jun 7 2011, 00:14)  static убрать убрать статик - не помогает явно привести тип к любому int - не помогает определять массив с указателями в PROGMEM - помогает.
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jun 7 2011, 06:48
|

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

|
CODE static void test() {
}
#define adr(x) ((uint16_t)(x) & 0xFF), ((uint16_t)(x) & 0xFF00) >> 8
uint8_t Test[] = { adr(test), (uintptr_t)test >> 0, (uintptr_t)test >> 8, (uintptr_t)test >> 16, (uintptr_t)test >> 24, }; QUOTE Compiling: main.cpp main.cpp:50: warning: right shift count >= width of type main.cpp:51: warning: right shift count >= width of type что и следовало ожидать - размер uintptr_t - 2 байта. Так что ищите проблему в другом месте.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 7 2011, 09:33
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Сергей Борщ @ Jun 7 2011, 10:48)  Так что ищите проблему в другом месте. Код #include "plc_editor.h" static void foo(void){ }
#define adr(x) ((uint16_t)(x) & 0x00FF), ((uint16_t)(x)>>8)
uint8_t array[] = { adr(foo) }; Цитата Building file: ../plc_editor.c Invoking: AVR Compiler avr-gcc -Wall -g3 -gdwarf-2 -O0 -fpack-struct -fshort-enums -std=gnu99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=16000000UL -MMD -MP -MF"plc_editor.d" -MT"plc_editor.d" -c -o"plc_editor.o" "../plc_editor.c" ../plc_editor.c:27: error: initializer element is not constant ../plc_editor.c:27: error: (near initialization for 'array[0]') ../plc_editor.c:28: error: initializer element is not constant ../plc_editor.c:28: error: (near initialization for 'array[1]') make: *** [plc_editor.o] Error 1 и где искать?
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jun 7 2011, 10:12
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Код static void foo1(void){} static void foo2(void){}
typedef union { void (*foo)(void); uint8_t bytes[sizeof(void*)]; } union_t;
const union_t array[] = { foo1, foo2 }; Смените подход. И объявите union вашего пакета данных и массива байт. Цитата(Сергей Борщ @ Jun 7 2011, 10:48)  что и следовало ожидать - размер uintptr_t - 2 байта. Так что ищите проблему в другом месте. C++ != С
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 7 2011, 10:26
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Сергей Борщ @ Jun 7 2011, 14:19)  Бага. В режиме С++ все компилится. И массив из указателей на функции в режиме С создается. А вот на приведении указателя с целому - спотыкается. Пишите баг-репорт. Думаю что с багрепортом рановато. Нужно стандарт изучить на сей счёт ибо и RealView-MDK-ARM - тоже даёт предупреждение, но проект собирает. Хотя и по моему мнению разницы быть не должно, что приводишь к целому что нет. 2ТС: Cмените диалект с gnu99 на c99. Есть разница?
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jun 7 2011, 11:01
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Код static void foo(void){ }
static uint8_t array[] = {foo}; Цитата Building file: ../plc_editor.c Invoking: AVR Compiler avr-gcc -Wall -g3 -gdwarf-2 -O0 -fpack-struct -fshort-enums -std=c99 -funsigned-char -funsigned-bitfields -mmcu=atmega32 -DF_CPU=16000000UL -MMD -MP -MF"plc_editor.d" -MT"plc_editor.d" -c -o"plc_editor.o" "../plc_editor.c" ../plc_editor.c: At top level: ../plc_editor.c:95: warning: initialization makes integer from pointer without a cast ../plc_editor.c:95: error: initializer element is not computable at load time ../plc_editor.c:95: error: (near initialization for 'array[0]') make: *** [plc_editor.o] Error 1 ну на счет предупреждений - бог с ними, но пишет ведь ошибку - элемент не может быть вычислен на этапе компиляции! в run-time я могу записать туда адрес любой функции, не проходит только инициализация
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jun 7 2011, 11:40
|

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

|
QUOTE (ARV @ Jun 7 2011, 14:01)  не проходит только инициализация CODE static void foo(void){ }
typedef void (*fptr)(); fptr array[] = { foo }; Компиляция проходит. Проблема начинается при попытке занести в массив целых чисел.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 7 2011, 12:15
|

Профессионал
    
Группа: Свой
Сообщений: 1 143
Регистрация: 30-09-08
Из: Новочеркасск
Пользователь №: 40 581

|
Цитата(Сергей Борщ @ Jun 7 2011, 15:40)  Компиляция проходит. Проблема начинается при попытке занести в массив целых чисел. совершенно верно! причем если массив uint16_t - то тоже пролетает на ура (с варнингами о преобразовании указателя в целое), а вот uint8_t дает ошибку... то есть это БАГ? по идее ведь батовый массив или не байтовый - какая разница для Си?
--------------------
Я бы взял частями... но мне надо сразу.
|
|
|
|
|
Jun 7 2011, 14:35
|

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

|
QUOTE (ARV @ Jun 7 2011, 15:15)  совершенно верно! причем если массив uint16_t - то тоже пролетает на ура (с варнингами о преобразовании указателя в целое), А если сделать явное приведение - не ругается. QUOTE (ARV @ Jun 7 2011, 15:15)  а вот uint8_t дает ошибку... то есть это БАГ? Да. Причем бага именно avr-gcc. Потому что именно avr-gcc ругается (проверил и на 3.4.6 и на 4.3.3), в то время как mingw-gcc прекрасно компилит.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jun 10 2011, 07:38
|
Участник

Группа: Validating
Сообщений: 56
Регистрация: 15-10-06
Пользователь №: 21 335

|
Хм ... а можно дурацкий вопрос ? откуда компилятор возмет адрес функции что-бы вычислить значение adr(x) ?? IMHO адрес может проявиться только на этапе сборки (если не выпендриваться с __attribute__ ) ?
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|