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

 
 
> IAR AVR 4.10A, Обойти ограничение
Sergio66
сообщение Mar 16 2005, 13:46
Сообщение #1


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Как можно обойти ограничение Embedded C++ на арифметику с enum типом?
Компиллятор грязно ругается на сл. строчку:
current_item += i;, где current_item - enum переменная, i - int.
Go to the top of the page
 
+Quote Post
 
Start new topic
Ответов
Sergio66
сообщение Mar 16 2005, 15:56
Сообщение #2


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(Sergio66 @ Mar 16 2005, 16:46)
Как можно обойти ограничение Embedded C++ на арифметику с enum типом?
Компиллятор грязно ругается на сл. строчку:
current_item += i;, где current_item - enum переменная, i - int.
*


Ругань идет даже на выражение такого типа: current_item ++; тип current_item - enum !!!
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 17 2005, 06:34
Сообщение #3


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Sergio66 @ Mar 16 2005, 21:56)
Ругань идет даже на выражение такого типа: current_item ++; тип current_item - enum !!!
*

Вам же совершенно правильно объяснили, что так делать в С++ нельзя. Перечислимый тип - он только представление имеет в виде целого, а суть у него иная. И идея, и реализация в С++ логичны. В отличие от С, где с enum'ом можно делать что угодно - какое вообще смысл в этом перечислении в С, не понятно!

А в С++ объект перечислимого типа может принимать только значения своего типа. Прямое присвоение целого и арифметика запрещены. Сами посудите: вот есть у Вас

Код
enum TSlon
{
   slon    = 0,
   slonick = 3,
   mamont  = 5
} Slon;


Теперь Вы пишете: Slon = 2; Какому значению типа TSlon оно будет соответствовать? Правильно - несущетсвующему, т.е. налицо нарушение самой идеи перечислимого типа: ведь он только для того и заведен, чтобы создать и манагить некое подмножетство целых. Те, которые не описаны в нем, это невалидные значения. И компилятор при статическом контроле типов эффективно подавляет подобные ошибки.

Аналогичная ситуация и с арифметикой - результат арифметической операции может порождать значение, отсутсвующее в перечислимом типе.

Единственное, что enum связывает с преобразованиями типов и целыми - это неявное преобразование значения объекта перечислимого типа в целое.

Если уж очень хоцца присвоить объекту enum'а целое. то можно пользоваться насильным приведением типа: Slon = (TSlon)2; Но применение явного приведения типа означает, что "компилятор в этом случае умывает руки и говорит: "Надеюсь, парень, ты знаешь, что делаешь!" (с). И вообще, как сказал один лобастый дядька, явное приведение типа обычно указывает на ошибку этапа проектирования. Т.е. в правильно спроектированном коде необходимости в использовании явного преобразования типа не возникает. Исключения составляют всякие низкоуровеневые вещи вроде работы с аппаратурой и прочие "финты ушами". Для того они и оставлены в языке. Но это не есть красивый правильный подход во всех остальных случаях. Привычка постоянно использовать явные преобразования - источник собственноручно разложенных граблей.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Sergio66
сообщение Mar 17 2005, 13:59
Сообщение #4


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Цитата(dxp @ Mar 17 2005, 09:34)
Цитата(Sergio66 @ Mar 16 2005, 21:56)
Ругань идет даже на выражение такого типа: current_item ++; тип current_item - enum !!!
*


А в С++ объект перечислимого типа может принимать только значения своего типа. Прямое присвоение целого и арифметика запрещены. Сами посудите: вот есть у Вас

Код
enum TSlon
{
   slon    = 0,
   slonick = 3,
   mamont  = 5
} Slon;


Теперь Вы пишете: Slon = 2; Какому значению типа TSlon оно будет соответствовать? Правильно - несущетсвующему, т.е. налицо нарушение самой идеи перечислимого типа: ведь он только для того и заведен, чтобы создать и манагить некое подмножетство целых. Те, которые не описаны в нем, это невалидные значения. И компилятор при статическом контроле типов эффективно подавляет подобные ошибки.

*



А теперь представьте задачку - (из того же примера) нужно выбрать следующее за slon значение переменной Slon. (аналогично i++). И как?
Go to the top of the page
 
+Quote Post
dxp
сообщение Mar 18 2005, 07:19
Сообщение #5


Adept
******

Группа: Свой
Сообщений: 3 469
Регистрация: 6-12-04
Из: Novosibirsk
Пользователь №: 1 343



Цитата(Sergio66 @ Mar 17 2005, 19:59)
А теперь представьте задачку - (из того же примера) нужно выбрать следующее за slon значение переменной Slon. (аналогично i++). И как?


У Вас типичная ошибка этапа проектирования: Вы неправильно выбрали тип для реализации требуемой Вам функциональности. enum тут не подходит.

Если Вам нужно просто целое, то и используйте его. Если Вам не нравится, то целое - голое, без "обвески", то приделайте обвеску - напишите класс. Типа:

Код
class TSlon
{
public:
   TSlon() : Value(0)       { }
   TSlon(int x) : Value(x) { }
   TSlon(const TSlon& x) : Value(x) { }
   void Increase() { Value++; if(Value > MAX_VAL) Value = 0; } // wrap around
   void Decrease() { Value--; if(Value < 0) Value = MAX_VAL; } // wrap around }
   void operator ++() { Increase(); }
   void operator --() { Decrease(); }
   operator int() { return Value; }
   ... // остальной интерфейс, если он требуется

private:
   int Value;
}


Тут у вас будет максимум и там, и там. И производительность максимальная, и безопасность использования. Вообще-то, С++ для этого и придуман - чтобы сочетать скорость С с безопасностью и удобством более высокоуровевых языков.

P.S. Вообще-то, интерфейсы с меню не так пишутся. Там удобно использовать иерархию полиморфных классов и виртуальные функции. Получается удобно, быстро, безопасно и расширяемо.

P.P.S. И ничего не мешает делать так, как делали на прежнем пакете - включите С режим (не используйте ключи --ec++/--eec++) и будет вам щастье smile.gif, можете мучить этот енум как заблагорассудтся. Только уже если что, не компилятор не пеняйте. smile.gif

[FONT=Courier]


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
Sergio66
сообщение Mar 18 2005, 10:16
Сообщение #6


Местный
***

Группа: Свой
Сообщений: 235
Регистрация: 9-02-05
Пользователь №: 2 526



Здесь была длинная и ненужная цитата. В следующий раз будет предупреждение
Все верно, только при разработке проекта 2 года назад был выбран компиллятор ICC. Теперь остается только облизываться на прелести С++; Переписывать 20 000 строк под С++ никакой бюджет не выдержит smile.gif)

Сообщение отредактировал IgorKossak - Mar 18 2005, 10:33
Go to the top of the page
 
+Quote Post



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

 


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


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