Помощь - Поиск - Пользователи - Календарь
Полная версия этой страницы: БАг в компиляторе или не баг
Форум разработчиков электроники ELECTRONIX.ru > Микроконтроллеры (MCs) > Cредства разработки для МК > IAR
MALLOY2
IAR 5.50.1

Имеем структуру
Код
typedef struct usb_common_descriptor_tag
{
u8_t  bLength;
u8_t  bDescriptorType;
} usb_common_descriptor_t;


Код который выдает ошибку при компиляци
Код
usb_common_descriptor_t *ptr;
...
(u8_t*)ptr += ptr-> bLength;


Ошибка:
Цитата
Error[Pe137]: expression must be a modifiable lvalue ...


Если написать так
Код
usb_common_descriptor_t *ptr;
u8_t *ptr8;
...
ptr8 = (u8_t*)ptr;
ptr8 +=  ptr-> bLength;
ptr = (usb_common_descriptor_t*)ptr8;


Компилирует как надо, это я чего не понимаю или бяка в компилере ?
zltigo
QUOTE (MALLOY2 @ Jul 12 2010, 13:00) *
CODE
usb_common_descriptor_t *ptr;
...
(u8_t*)ptr += ptr-> bLength;

Бессмысленный cast для lvalue. Так ругаться не будет:
CODE
ptr += ptr-> bLength;
MALLOY2
Вы чего то не поняли, ptr-> bLength может быть любая длинна. Это все дескрипторы разного размера собраны в один массив, а этот код предназначен для их перебора в цикле, если я напишу так ptr += ptr-> bLength то ptr будет увеличен на sizeof(usb_common_descriptor_t) * ptr-> bLength, а мне надо увеличить ptr на 7.

P.S. lvalue тут вобще не приделах.

Мож так понятней

Код
    ptr = (usb_common_descriptor_t*)&USB_ConfigDescriptor;
    while(ptr->bLength)
    {
      switch (ptr->bDescriptorType)
      {
        case USB_CONFIGURATION_DESCRIPTOR_TYPE:
             ...
          break;
        case USB_INTERFACE_DESCRIPTOR_TYPE:    
             ...
          break;
        case USB_ENDPOINT_DESCRIPTOR_TYPE:      
             ...
          break;
       case USB_VENDOR_STATUS_TYPE:      
             ...
          break;
      }
      (u8_t*)ptr += ptr->bLength;
    };
Сергей Борщ
Цитата(MALLOY2 @ Jul 12 2010, 13:00) *
это я чего не понимаю или бяка в компилере ?
Да, правильно ругается. Попробуйте так:
Код
ptr = (usb_common_descriptor_t *)((uint8_t *)ptr + ptr->bLength);

zltigo
QUOTE (MALLOY2 @ Jul 12 2010, 13:40) *
P.S. lvalue тут вобще не приделах.

Совершенно при делах. На 'С' сast lvalue не предусмотрен.
Сергей Борщ
Цитата(MALLOY2 @ Jul 12 2010, 13:40) *
P.S. lvalue тут вобще не приделах.
При делах. Вы приводите тип левой части выражения, а этого делать нельзя. Возможно в предыдущих версиях стандарта и можно было, gcc 3.x такое пропускал. Более свежие - уже нет.
MALLOY2
Спасибо схавало, но Keil хавает и так (u8_t*)ptr += ptr-> bLength;


Цитата(zltigo @ Jul 12 2010, 13:48) *
Совершенно при делах. На 'С' сast lvalue не предусмотрен.


Извеняюсь, чего-то меня переклинило и я подумал речь идет о USB полях sad.gif.
zltigo
QUOTE (MALLOY2 @ Jul 12 2010, 13:50) *
Спасибо схавало, но Keil хавает и так (u8_t*)ptr += ptr-> bLength;

Это плохо sad.gif. Что-то подобное было, кажется, в древних проектах ANSI. Но не в 21 веке. Такой фигней страдал, например, эталон кривизны в компиляторостроении Борланд.
MALLOY2
Цитата
... Борланд.


Там меня наверное и заразило smile.gif
KRS
Так надо развернуть +=
CODE
  ptr = (usb_common_descriptor_t *)((u8_t*)ptr + ptr-> bLength);

длинно, но правильно. Потому что тут ДВА преобразования!
А код (u8_t*)ptr += ptr-> bLength - идеологически не верен!
Для просмотра полной версии этой страницы, пожалуйста, пройдите по ссылке.
Invision Power Board © 2001-2025 Invision Power Services, Inc.