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

 
 
> БАг в компиляторе или не баг
MALLOY2
сообщение Jul 12 2010, 10:00
Сообщение #1


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



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;


Компилирует как надо, это я чего не понимаю или бяка в компилере ?
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов (1 - 9)
zltigo
сообщение Jul 12 2010, 10:31
Сообщение #2


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (MALLOY2 @ Jul 12 2010, 13:00) *
CODE
usb_common_descriptor_t *ptr;
...
(u8_t*)ptr += ptr-> bLength;

Бессмысленный cast для lvalue. Так ругаться не будет:
CODE
ptr += ptr-> bLength;


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 12 2010, 10:40
Сообщение #3


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Вы чего то не поняли, 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;
    };
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 12 2010, 10:46
Сообщение #4


Гуру
******

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



Цитата(MALLOY2 @ Jul 12 2010, 13:00) *
это я чего не понимаю или бяка в компилере ?
Да, правильно ругается. Попробуйте так:
Код
ptr = (usb_common_descriptor_t *)((uint8_t *)ptr + ptr->bLength);



--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 12 2010, 10:48
Сообщение #5


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



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

Совершенно при делах. На 'С' сast lvalue не предусмотрен.


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение Jul 12 2010, 10:48
Сообщение #6


Гуру
******

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



Цитата(MALLOY2 @ Jul 12 2010, 13:40) *
P.S. lvalue тут вобще не приделах.
При делах. Вы приводите тип левой части выражения, а этого делать нельзя. Возможно в предыдущих версиях стандарта и можно было, gcc 3.x такое пропускал. Более свежие - уже нет.


--------------------
На любой вопрос даю любой ответ
"Write code that is guaranteed to work, not code that doesn’t seem to break" (C++ FAQ)
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 12 2010, 10:50
Сообщение #7


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Спасибо схавало, но Keil хавает и так (u8_t*)ptr += ptr-> bLength;


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


Извеняюсь, чего-то меня переклинило и я подумал речь идет о USB полях sad.gif.
Go to the top of the page
 
+Quote Post
zltigo
сообщение Jul 12 2010, 10:53
Сообщение #8


Гуру
******

Группа: Свой
Сообщений: 13 372
Регистрация: 27-11-04
Из: Riga, Latvia
Пользователь №: 1 244



QUOTE (MALLOY2 @ Jul 12 2010, 13:50) *
Спасибо схавало, но Keil хавает и так (u8_t*)ptr += ptr-> bLength;

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


--------------------
Feci, quod potui, faciant meliora potentes
Go to the top of the page
 
+Quote Post
MALLOY2
сообщение Jul 12 2010, 11:01
Сообщение #9


Знающий
****

Группа: Validating
Сообщений: 838
Регистрация: 31-01-05
Пользователь №: 2 317



Цитата
... Борланд.


Там меня наверное и заразило smile.gif
Go to the top of the page
 
+Quote Post
KRS
сообщение Jul 13 2010, 12:44
Сообщение #10


Профессионал
*****

Группа: Модераторы
Сообщений: 1 951
Регистрация: 27-08-04
Из: Санкт-Петербург
Пользователь №: 555



Так надо развернуть +=
CODE
  ptr = (usb_common_descriptor_t *)((u8_t*)ptr + ptr-> bLength);

длинно, но правильно. Потому что тут ДВА преобразования!
А код (u8_t*)ptr += ptr-> bLength - идеологически не верен!
Go to the top of the page
 
+Quote Post

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

 


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


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