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

 
 
> функция с переменным числом аргументов, экономная реализация в IAR
andrvisht
сообщение May 23 2006, 06:09
Сообщение #1


Местный
***

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



написал функцию для передачи переменного числа аргументов
Код
#include <stdarg.h>
void foo(unsigned char a, ...);
unsigned char A[5];
void foo(unsigned char a, ...)
{
char i;
  va_list arg_ptr;
  va_start(arg_ptr, a);
  for(i = 0; i < a; ++i)
    A[i]=va_arg(arg_ptr, unsigned char);
  va_end(arg_ptr);
}

void main(void)
{
  unsigned char b = '4', c = 'A';
  foo (5,23,b,32,c);
}

т.е. заполнение массива указанным числом аргументов, результат её работы получил следующий
A[] = {0x17, 0x00, 0x34, 0x00, 0x20}
как видно компилятор приводит мои аргументы к int. Для передачи числа 23 или 32 это еще можно понять, но как быть с явно указанными b и c ?

Попробовал данный код в Image Craft - результат тот-же, а вот Code Vision поступил честно (?)
и передал все параметры b и c как char.

Далее читаю help от IAR и узнаю что аргументом не может быть any integer type that changes when promoted естественно возник интерес к слову promoted и поиск по help дал следующее

Argument promotion occurs when the type of the function fails to provide any information about an argument. Promotion occurs if the function declaration is not a function prototype or if the argument is one of the unnamed arguments in a varying number of arguments. In this instance, the argument must be an rvalue expression.

на основании перевода (возможно неправильного) стало понятно что должна существовать возможность указания типа аргумента для неименованых аргументов в функции с переменным их числом, но как это сделать ... ?
PS: в книгах по С все приводимые примеры относятся к типу int sad.gif
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
_Bill
сообщение May 23 2006, 11:38
Сообщение #2


Местный
***

Группа: Участник
Сообщений: 416
Регистрация: 18-04-06
Из: Челябинск
Пользователь №: 16 219



Цитата(&-rey @ May 23 2006, 09:09) *
написал функцию для передачи переменного числа аргументов
Код
#include <stdarg.h>
void foo(unsigned char a, ...);
unsigned char A[5];
void foo(unsigned char a, ...)
{
char i;
  va_list arg_ptr;
  va_start(arg_ptr, a);
  for(i = 0; i < a; ++i)
    A[i]=va_arg(arg_ptr, unsigned char);
  va_end(arg_ptr);
}

void main(void)
{
  unsigned char b = '4', c = 'A';
  foo (5,23,b,32,c);
}

т.е. заполнение массива указанным числом аргументов, результат её работы получил следующий
A[] = {0x17, 0x00, 0x34, 0x00, 0x20}
как видно компилятор приводит мои аргументы к int. Для передачи числа 23 или 32 это еще можно понять, но как быть с явно указанными b и c ?

Видимо, тут вся проблема в оптимизации. Компилятор подставляет в аргументы функции не значения переменных b и c, а константы, которыми эти переменные проинициализированы. А поскольку константы всегда имеют тип int, то и получается то, что получилось. В общем, надо посмотреть сгенерированный код.
Go to the top of the page
 
+Quote Post
andrvisht
сообщение May 23 2006, 12:04
Сообщение #3


Местный
***

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



Цитата(_Bill @ May 23 2006, 14:38) *
Видимо, тут вся проблема в оптимизации. Компилятор подставляет в аргументы функции не значения переменных b и c, а константы, которыми эти переменные проинициализированы. А поскольку константы всегда имеют тип int, то и получается то, что получилось. В общем, надо посмотреть сгенерированный код.

от оптимизации это не зависит, и даже обьявление b и c как глобальных переменных со спецификатором volatile которое могло бы устранить такое недоразумение (имеется ввиду подставление константы вместо переменной) не помогло sad.gif
а код собственно сгенерить не сложно, вот он:
Код
main:
    00004C   9100 00D3        LDS     R16,c
    000050   E010             LDI     R17,0x00
    000052   931A             ST      -Y,R17
    000054   930A             ST      -Y,R16
    000056   E200             LDI     R16,0x20
    000058   E010             LDI     R17,0x00
    00005A   931A             ST      -Y,R17
    00005C   930A             ST      -Y,R16
    00005E   9100 00D2        LDS     R16,b
    000062   E010             LDI     R17,0x00
    000064   931A             ST      -Y,R17
    000066   930A             ST      -Y,R16
    000068   E107             LDI     R16,0x17
    00006A   E010             LDI     R17,0x00
    00006C   931A             ST      -Y,R17
    00006E   930A             ST      -Y,R16
    000070   E005             LDI     R16,0x05
    000072   DFD9             RCALL   foo
    000074   9628             ADIW    R28,8

явно видно что компилятор приводит все к int
вопрос в том как указать IAR что данные параметры будут char хотя не исключено, что это стандарт, и изменение его IAR не делает, что вообщем то правильно. Но так ли это ? хочется ясности.
Go to the top of the page
 
+Quote Post

Сообщений в этой теме


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

 


RSS Текстовая версия Сейчас: 25th July 2025 - 17:38
Рейтинг@Mail.ru


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