Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: IARCompiler V4.30A-P050906/W32
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > ARM
zltigo
Многкратно мною ранее портированный на разные платформы и компилированный пятью
компиляторами текст вызова по адресу, типа:

( (void(*)())arg )( (char *)pvalue );


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

Только не у IAR ARM ANSI C/C++ Compiler V4.30A-P050906/W32 (другие не пробовал в ввиду отсутствия истории работ с IAR). У IAR вопль НЕ ОТКЛЮЧАЕТСЯ!
Ни "#pragma diag_suppress=Pa046", ни ключем в командной строке. Не удается и перевести
в разряд "remarks" или "warnings". Только фатальная ошибка. Дурдом какой-то.

Кто-то знает, как заставить IAR работать?
_artem_
Ne dolzno li bit eto kak :

( (void(*)(char*))arg )( (char *)pvalue );

?

Pitayetes li vi casting delat dlja pointera to function arg
vozvrasayusego void i imeyusego pointer to char argument? Popravte menaj esli ya ne prav. Da ese mozete li napisat prototip funkcii kotoriy vy sobiraetes vyzyva iz pamjati ?
zltigo
Цитата(_artem_ @ Dec 5 2005, 23:50) *
Ne dolzno li bit eto kak :
( (void(*)(char*))arg )( (char *)pvalue );
Pitayetes li vi casting delat dlja pointera to function arg
vozvrasayusego void i imeyusego pointer to char argument? Popravte menaj esli ya ne prav. Da ese mozete li napisat prototip funkcii kotoriy vy sobiraetes vyzyva iz pamjati ?


Вполне правильный casting :-( и понимается C компилятором.
Как и вариант
( (void (*)(...))arg )( (char *)pvalue );
для С++

Едиственная проблема, что прототипа нет и не может??? быть, ибо 'arg' это переменная содержащая адрес а сама функция АБСТРАКТНА. Если можете сказать КАК описать прототип функции без имени -
скажите. Моего 20 летнего опыта не хватает для этого.
_artem_
I che v golovu ne prislo chto u vas variable argument list function ?)))

'arg' u vas kakogo tipa? Esli on otlichaertsja ot void* to casting ne budet delatsja (vidaetsja osibka) - eto standartom C tak i opisyvaetsja.

Vam togda nado perepisat tak :

( (void(*)()) ((void*)arg ))( (char *)pvalue );


dlja udobstva mozete ese i typedef'i delat dlja funkcii pointera .
zltigo
Цитата(_artem_ @ Dec 6 2005, 00:35) *
'arg' u vas kakogo tipa? Esli on otlichaertsja ot void* to casting ne budet delatsja (vidaetsja osibka) - eto standartom C tak i opisyvaetsja.


Похоже Вы путаете с перобразованием типов по умолчанию.....
С casting проблем нет, arg именно void*. Что, впрочем не имеет значения, ибо уже
указано явное преобразование типов. Два раза преобразовывать перебор, хотя компилятору можно и
десять указать - скорее всего не заругается, хотя я не пробовал :-).
Ошибка выдается на отсутствию прототипа, что абсолютно ПРАВИЛЬНО.
Проблема в том, что это ОШИБКА и НЕ ОТКЛЮЧАЕТСЯ.
_artem_
Ya s samogo nachala ponyal chto vy xotite otkljuchit detektirovanie etoj osibki, prosto podumal chto mozno problemu oboyti .))
Mdaaaaa, mne samomu interesno stalo vzjal nemnogo po standartu proselsja. Dumayu chto vy eto znaete uze davno , podpravte menja esli ja neverno govoryu .

Standard govorit chto (6.9.1 Syntax rule 8) :
"If a function that accepts a variable number of arguments is defined without a parameter type list that ends with the ellipsis notation, the BEHAVIOR IS UNDEFINED."

V svoyu ochered syntax pishet dla argumentov:

parameter-type-list:
parameter-list
parameter-list , ...

Vrode by poluchaetsja chto kak minimum odin identifier dolzen byt pered ellipsisom chtoby compiler ego prinjal. Esli u vas vse pervye argumenty- pointery , to mozno funkciyu perepisat kak :

typedef void(*fptr)(void*,...);

((fptr)(arg))(pvalue);

Proveril na Borlande - tak i est. Mozet byt eto vyxod?
Est li tam ptichka s podderzkoj K&R standarta Cv settingax?
Mozet otmetit ee?
VAI
Цитата
( (void(*)())arg )( (char *)pvalue );


Если цель: вызвать функцию, располагающуюся по адресу arg с параметром pvalue, то я так делаю для MSP. А ARM-е новичек, вот попробовал в таком-же, как у Вас ИАРе, варнингов нет, ероров тоже
Код
режим __arm
     22          // Вызов функции по mam_Init или адресу 0x40000000
     23          ( (void(*)()) mam_Init )( (char *)23 );
   \   00000008   1700A0E3           MOV         R0,#+0x17
   \   0000000C   ........           _BLF        mam_Init,mam_Init??rA
     24          ( (void(*)()) mam_Init )( (char *)a );
   \   00000010   0000A0E3           MOV         R0,#+0
   \   00000014   ........           _BLF        mam_Init,mam_Init??rA
     25          
     26          ( (void(*)()) 0x40000000 )( (char *)23 );
   \   00000018   1700A0E3           MOV         R0,#+0x17
   \   0000001C   4014A0E3           MOV         R1,#+0x40000000
   \   00000020   0FE0A0E1           MOV         LR,PC
   \   00000024   11FF2FE1           BX          R1
     27          ( (void(*)()) 0x40000000 )( (char *)a );
   \   00000028   0400A0E1           MOV         R0,R4
   \   0000002C   4014A0E3           MOV         R1,#+0x40000000
   \   00000030   0FE0A0E1           MOV         LR,PC
   \   00000034   11FF2FE1           BX          R1
     28          
     29          // Вызов функции по  вектору содержащемуся вmam_Init или  0x40000000
     30          ( *( void( ** )()) mam_Init )();
   \   00000038   ........           LDR         R5,??DataTable1   ;; mam_Init
   \   0000003C   000095E5           LDR         R0,[R5, #+0]
   \   00000040   0FE0A0E1           MOV         LR,PC
   \   00000044   10FF2FE1           BX          R0
     31          ( *( void( ** )()) mam_Init )( (char *)a );
   \   00000048   0400A0E1           MOV         R0,R4
   \   0000004C   001095E5           LDR         R1,[R5, #+0]
   \   00000050   0FE0A0E1           MOV         LR,PC
   \   00000054   11FF2FE1           BX          R1
     32          
     33          ( *( void( ** )()) 0x40000000 )();
   \   00000058   4004A0E3           MOV         R0,#+0x40000000
   \   0000005C   000090E5           LDR         R0,[R0, #+0]
   \   00000060   0FE0A0E1           MOV         LR,PC
   \   00000064   10FF2FE1           BX          R0
     34          ( *( void( ** )()) 0x40000000 )( (char *)a );
   \   00000068   0400A0E1           MOV         R0,R4
   \   0000006C   4014A0E3           MOV         R1,#+0x40000000
   \   00000070   001091E5           LDR         R1,[R1, #+0]
   \   00000074   0FE0A0E1           MOV         LR,PC
   \   00000078   11FF2FE1           BX          R1
     35          
     36          

thumb
     22          // Вызов функции по mam_Init или адресу 0x40000000
     23          ( (void(*)()) mam_Init )( (char *)23 );
   \   00000004   1720               MOV         R0,#+0x17
   \   00000006   ........           _BLF        mam_Init,mam_Init??rT
     24          ( (void(*)()) mam_Init )( (char *)a );
   \   0000000A   0020               MOV         R0,#+0
   \   0000000C   ........           _BLF        mam_Init,mam_Init??rT
     25          
     26          ( (void(*)()) 0x40000000 )( (char *)23 );
   \   00000010   8026               MOV         R6,#+0x80
   \   00000012   F605               LSL         R6,R6,#+0x17      ;; #+0x40000000
   \   00000014   1720               MOV         R0,#+0x17
   \   00000016   ........           BL          ??rT_BX_R6
     27          ( (void(*)()) 0x40000000 )( (char *)a );
   \   0000001A   281C               MOV         R0,R5
   \   0000001C   ........           BL          ??rT_BX_R6
     28          
     29          // Вызов функции по  вектору содержащемуся вmam_Init или  0x40000000
     30          ( *( void( ** )()) mam_Init )();
   \   00000020   ....               LDR         R6,??DataTable1   ;; mam_Init
   \   00000022   3068               LDR         R0,[R6, #+0]
   \   00000024   ........           BL          ??rT_BX_R0
     31          ( *( void( ** )()) mam_Init )( (char *)a );
   \   00000028   281C               MOV         R0,R5
   \   0000002A   3168               LDR         R1,[R6, #+0]
   \   0000002C   ........           BL          ??rT_BX_R1
     32          
     33          ( *( void( ** )()) 0x40000000 )();
   \   00000030   8026               MOV         R6,#+0x80
   \   00000032   F605               LSL         R6,R6,#+0x17      ;; #+0x40000000
   \   00000034   3068               LDR         R0,[R6, #+0]
   \   00000036   ........           BL          ??rT_BX_R0
     34          ( *( void( ** )()) 0x40000000 )( (char *)a );
   \   0000003A   281C               MOV         R0,R5
   \   0000003C   3168               LDR         R1,[R6, #+0]
   \   0000003E   ........           BL          ??rT_BX_R1
     35
zltigo
Цитата(_artem_ @ Dec 6 2005, 03:53) *
typedef void(*fptr)(void*,...);
((fptr)(arg))(pvalue);

Месье знает толк в извращениях :-). Спасибо!, что столкнули меня с тупиковых раздумий о
прототипах.
((void(*)( void *))arg)( (char *)pvalue );
Это решение!

P.S.
Напомнило концовку анекдота застойных времен - "я не знаю, кто он такой, но водителем у него
Брежнев работает".

P.P.S.
На свежую голову заметил, что оказывается IDE сгенерила для компилятора дивный ключик:
--require_prototypes
Причем 'галочка' находилась в разделе "language" а отнюдь не в "Diagnostics" со всеми остальными.
Пора с этой IDE завязывать и под make.
Естественно, если ключик убрать, то компилятор забывает начисто о прототипах, настолько забывает, что контроль теперь не включается ни
#pragma diag_warning=Pa046
ни как по другому. Короче, явный баг компилятора....
zltigo
Цитата(VAI @ Dec 6 2005, 07:46) *
Если цель: вызвать функцию, располагающуюся по адресу arg с параметром pvalue, то я так делаю для MSP. А ARM-е новичек, вот попробовал в таком-же, как у Вас ИАРе, варнингов нет, ероров тоже

В том-то и дело, что работало до сих пор на доброй дюжине компиляторов. Претензии есть к конкретному компилятору :-(.
Хорошо, что найдено наиправильнейшее решение.
Хотя если IAR компилятор для MSP не генерит варнинги (они у него не отключены начисто)
то тогда у меня к нему тоже претензии есть :-) и БОЛЬШИЕ :-)
VAI
Да варнингов и не должно быть. Что я и показал в примере, который скомпилил используя "IAR C/C++ Compiler for ARM 4.30A-P050906 (4.30.1.500)"
Цитата
( (void(*)())arg )( (char *)pvalue );

При подобном вызове нет нужды в прототипах, т.к. приведение типов производится ручками.
А вот если у Вас неопределены arg и/или pvalue - тогда должны быть.
zltigo
Цитата(VAI @ Dec 6 2005, 13:18) *
Да варнингов и не должно быть. Что я и показал в примере, который скомпилил используя "IAR C/C++ Compiler for ARM 4.30A-P050906 (4.30.1.500)"
Цитата
( (void(*)())arg )( (char *)pvalue );

При подобном вызове нет нужды в прототипах, т.к. приведение типов производится ручками.
А вот если у Вас неопределены arg и/или pvalue - тогда должны быть.

Не правда Ваша :-(.
arg и pvalue естественно определены и на такой вариант должна быть ругань и ругаются следующие компиляторы:
Zortech C
BC (3.1....5)
GCC (разные платформы и разные целевые процессоры)
Watcom 11 (dos и W32)
Visual C
OpenWatcom (dos и W32)
V4.30A-P050906/W32

С каким ключем вообще НЕ ругается последний упомянутый, я уже писал.
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.