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

 
 
3 страниц V   1 2 3 >  
Reply to this topicStart new topic
> CPP enum с минусовыми значениями, насколько это правильно
k155la3
сообщение May 25 2017, 06:25
Сообщение #1


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Вопрос касается кода возврата функции, а именно удачно или нет она отработала.
Если плюс - удачно, информация в коде возврата - справочная.
Если минус - критичная ошибка, ф-ия не отработала.

(?) Насколько такой подход (с отрицательным enum) правильный-феншуйный-политкорректный ?

ps - minus_4 итд приведено для наглядности, в реале - ест-но - там симв. имя ошибки вроде eErr_ADC_Ready

А реализовал так:
Код
enum TEnum
{
    minus_4 = -4,
    minus_3,
    minus_2,
    minus_1,
    null_0 = 0,
    plus_1,
    plus_2,
    plus_3,
    plus_4
} my_enum;

. . .

int MyFun(void) {    ... ... ...   return(minus_2); ..... .... return(plus_3); }

. . .

RetCode = MyFun();

if( RetCode > 0 )
{
   . . . .  ошибок нет, в RetCode в инф. о статусе выполнения.
}
else  // минусы и 0
{
   . . . .  разбор ошибок
}


Сообщение отредактировал k155la3 - May 25 2017, 07:20
Go to the top of the page
 
+Quote Post
novikovfb
сообщение May 25 2017, 06:32
Сообщение #2


Знающий
****

Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450



Почему бы и нет. Одно не понятно: чем запись minus_4 лучше простой константы -4? Логичнее было бы вместо minus_4 указать наименование типа ошибки.
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 25 2017, 06:35
Сообщение #3


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(novikovfb @ May 25 2017, 09:32) *
Почему бы и нет. Одно не понятно: чем запись minus_4 лучше простой константы -4? Логичнее было бы вместо minus_4 указать наименование типа ошибки.

Константы надо "изобретать" вручную, а меня это утомляет sm.gif
Кроме того с символическими именами которые предоставляет enum работать в миллион раз удобнее чем с цифровыми кодами.

ps - пардон, я может неверно сформулировал в примере кода. там minus_4 приведено для наглядности.
в реале - ест-но - там симв. имя ошибки вроде eErr_ADC_Ready


Сообщение отредактировал k155la3 - May 25 2017, 06:37
Go to the top of the page
 
+Quote Post
_pv
сообщение May 25 2017, 07:22
Сообщение #4


Гуру
******

Группа: Свой
Сообщений: 2 563
Регистрация: 8-04-05
Из: Nsk
Пользователь №: 3 954



Цитата
integer constant expression whose value is representable as a value of type int

Go to the top of the page
 
+Quote Post
k155la3
сообщение May 25 2017, 07:32
Сообщение #5


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



"integer constant expression whose value is representable as a value of type int"
- это в смысле что int по умолчанию signed, соответственно минус можно использовать.
Насколько я понял.

По синтаксису компилятор это, естественно, допускает.

Интересует "практика" использования отрицательных enum.
Go to the top of the page
 
+Quote Post
AnatolyT
сообщение May 25 2017, 08:00
Сообщение #6


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 29-03-10
Пользователь №: 56 269



Постоянно применяю, только не enum, а int. Обычная практика, если функция возвращает отрицательное значение, это тип ошибки, если ноль или положительное значение, то все Ок или результат. С enum не пробовал, а зачем, int можно преобразовать или интерпретировать практически любым типом, как целое, символ или логическое значение. Удобно во вложенных функциях, возвращает тип ошибки на самый верх.
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 25 2017, 08:47
Сообщение #7


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(AnatolyT @ May 25 2017, 11:00) *
. . . .
Удобно во вложенных функциях, возвращает тип ошибки на самый верх.

Ok.

Я при "транизитном" возврате по ошибке, при каждом выходе "вверх", код ошибки умножаю на 10 - тогда видно с какого уровня
"всплыло". Более правильно наверно, использовать исключения, но пока делаю так.


Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 25 2017, 09:46
Сообщение #8


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(k155la3 @ May 25 2017, 11:32) *
Интересует "практика" использования отрицательных enum.

нормальная практика.
более интерено енум использовать с псевдонимами и комбинациями - например объявляеш флаги:
еА = 1, еБ = 2, еВ=4. еХ=0x10
и тут же объявляеш псевдонимы комбинаций
еЧеготоОбычное = еА | еХ
eНеобычное = еБ
еОшибка = еА |еБ |еХ
тожесамое = eНеобычное | еЧеготоОбычное

Меня другой момент использования енумов занимает - последнее время вижу что народ константы перечисления делает большими буквами, что обычно выглядит как макро.

Сообщение отредактировал AlexRayne - May 25 2017, 09:47
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 25 2017, 10:35
Сообщение #9


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(AlexRayne @ May 25 2017, 12:46) *
. . .
(1) более интерено енум использовать с псевдонимами и комбинациями - например объявляеш флаги
. . .
(2) Меня другой момент использования енумов занимает - последнее время вижу что народ константы перечисления делает большими буквами, что обычно выглядит как макро.

(1) да, допустим определены 10 констант - enum. При этом, если int 16-битный, задействовано только 4 разряда и то не полностью.
Оставшиеся 12 разрядов можно использовать для любой полезной инф - битовые флаги, поля итд. Фактически - структура.
Отрицательные значения - это один из вариантов этого.

(2) есть вроде не-дефакто-стандарты на именование различных типов. Тутуж кто-во-что горазд.
A - чтоб мне (любимому) было понятно
B - один из стандартов.
AB или BA приоритет ставят по разному.
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 25 2017, 12:27
Сообщение #10


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(k155la3 @ May 25 2017, 14:35) *
(1) да, допустим определены 10 констант - enum. При этом, если int 16-битный, задействовано только 4 разряда и то не полностью.
Оставшиеся 12 разрядов можно использовать для любой полезной инф - битовые флаги, поля итд. Фактически - структура.

да, легкая альтернатива структуре.
Цитата(k155la3 @ May 25 2017, 14:35) *
Отрицательные значения - это один из вариантов этого.

ну вариант не структуры, просто отрицательные числа используются. и на моей практике - как индикатор ошибки.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 25 2017, 12:47
Сообщение #11


Гуру
******

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



QUOTE (AlexRayne @ May 25 2017, 12:46) *
Меня другой момент использования енумов занимает - последнее время вижу что народ константы перечисления делает большими буквами, что обычно выглядит как макро.
Ну по смыслу такой enum эквивалентен набору макросов
CODE
#define TAG1 VALUE1
#define TAG2    (TAG1 + 1)
#define TAG3    (TAG2 + 1)
поэтому вполне ожидаемо и аналогичное правило записи имен.


--------------------
На любой вопрос даю любой ответ
"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
x893
сообщение May 25 2017, 16:36
Сообщение #12


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

Группа: Свой
Сообщений: 1 333
Регистрация: 27-10-08
Из: Планета Земля
Пользователь №: 41 226



По смыслу - enum это набор неизменяемых именованных значений, по умолчанию int, но можно и другого.
А вель можно еще её сделать типом и использовать в параметрах, тогда людям понятнее что передается и что возращается.
int Foo(..);
или
ERROR_STATUS Foo(...)

А разве это не написано в книжках ?

#define можно переопределить, а enum не получится.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 25 2017, 20:47
Сообщение #13


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Список ошибок часто определяю так:
enum {ERR_1 = 1, ERR_2, ERR_3, ERR_n}; //ну или от 0
А уж возврат ошибочного значения из функции тогда или:
return ERR_...;
или:
return -ERR_...;
А если нужно возвращать из функции или данный код ошибки или корректное состояние, заданное тоже enum-ом, то делаю иногда так:
enum {OK_0, OK_1, OK_2, OK_n};
return (int)OK_1; //корректное завершение с кодом OK_1
return (int)OK_n + (int)ERR_1 - 1; //завершение с ошибкой ERR_1
Т.е. - возвращаются всегда положительные значения. Для Thumb2 такой способ оптимальнее. cool.gif Кто знает асм - поймёт.

Цитата(k155la3 @ May 25 2017, 12:35) *
Оставшиеся 12 разрядов можно использовать для любой полезной инф - битовые флаги, поля итд. Фактически - структура.

Если нужно вернуть 2 параметра, то лучше и возвращать их как 2, а не лепить из них одно в точке return, и не распаковывать потом в точке вызова.
Если мне нужно например на 32-битной архитектуре вернуть 2 значения из функции, я делаю так:
u64 FuncA() {
u64 q = (u32)val1 | (u64)(u32)val2 << 32;
return q;
}
Если пытаться всё лепить в одно 32-битное значение, то будет куча лишних команд при упаковке и потом - при распаковке. А в вышеприведённом случае - минимум команд.
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 26 2017, 07:25
Сообщение #14


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(Сергей Борщ @ May 25 2017, 15:47) *
Ну по смыслу такой enum эквивалентен набору макросов
Код
#define TAG1 VALUE1
#define TAG2    (TAG1 + 1)
#define TAG3    (TAG2 + 1)
поэтому вполне ожидаемо и аналогичное правило записи имен.

По результату - да. По обработке и возможным "засадом" отличается.
enum просчитываются компилятором "за раз", а макросы - это головная боль препроцессора.
Так на какомнибуть TAG756 (сделанный копипастом) sm.gif на вход компилятора попадет:
Код
+ (TAG1)  
+ (TAG1+1) // TAG2
+ ((TAG1 + 1) + 1)  // TAG3
+ (((TAG1 + 1) + 1) + 1 ) // . . . .

... на шаге N у препроцессора (или у компилятора) срабатывает ограничение на длину строки (или списка).
(Это факт, по крайней мере для IAR/MSP430 5.40)
Причем никаких намеков ни Err, ни даже Warn компилятор не выдал.



Цитата(x893 @ May 25 2017, 19:36) *
. . . .
А разве это не написано в книжках ?

Да у меня вопрос собст-но про отрицательные enum. В литературе как-то не натыкался на это.
А проводить гугл-сеанс нет времени. Тем более можно спросить у "первоисточников" на этом форуме sm.gif


Цитата(jcxz @ May 25 2017, 23:47) *
Список ошибок часто определяю так:
. . . .

Ok - спасибо за инф. Надо осмыслить.

Go to the top of the page
 
+Quote Post
AnatolyT
сообщение May 26 2017, 09:11
Сообщение #15


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 29-03-10
Пользователь №: 56 269



Непонятно какие преимущества дает использование enum как типа возвращаемого значения функции.
Go to the top of the page
 
+Quote Post
novikovfb
сообщение May 26 2017, 09:46
Сообщение #16


Знающий
****

Группа: Участник
Сообщений: 518
Регистрация: 29-09-11
Пользователь №: 67 450



Цитата(AnatolyT @ May 26 2017, 13:11) *
Непонятно какие преимущества дает использование enum как типа возвращаемого значения функции.

1. компилятор проверит тип, если есть 2 различных функции, возвращающих коды завершения, имеющих разные наборы значений (и разные enum) - при перепутывании будет предупреждение.
2. символические константы содержат намек на смысловое значение кода, меньше гадать, что означает возврат кода 4.
Go to the top of the page
 
+Quote Post
Сергей Борщ
сообщение May 26 2017, 09:54
Сообщение #17


Гуру
******

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



QUOTE (novikovfb @ May 26 2017, 12:46) *
при перепутывании будет предупреждение.
В плюсах. В обычных Сях enum неявно приводится к int и обратно, поэтому предупреждения, насколько помню, не будет.

Добавлено: перечитал название темы...


--------------------
На любой вопрос даю любой ответ
"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
k155la3
сообщение May 26 2017, 10:01
Сообщение #18


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(AnatolyT @ May 26 2017, 12:11) *
Непонятно какие преимущества дает использование enum как типа возвращаемого значения функции.

Кроме очевидных преимуществ-удобств разгружающих моск.
Если Вы определили возвр. значение с типом enum, то при работе на отладке
Вы в Watch-окне будете видеть не абстрактные 12345 (и декодировать их вручную),
а символическое имя - в удобо-читаемом-понимаемом виде.

Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 26 2017, 10:10
Сообщение #19


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



По-моему идеально использовать enum по возможности так, чтобы было вообще всё равно какое там у него значение.
Оно так автоматически и получается, если везде работать с enum как с типом, а не пользоваться тем, что он может быть неявно преобразован в int.

Если все ошибки в вашей системе перечислены в enum и вам не нужно обеспечивать совместимость со сторонним кодом, где у ошибок есть конкретные int значения, то определите для ошибок тип
Цитата
typedef enum{
ERR_OK,
ERR_SOMETHING,
ERR_SOMETHING2
} Error_t;


Пусть все функции будут возвращать Error_t, а обработчики ошибок везде будут реагировать на ошибки путем обращения к ним по именам ERR_OK, ERR_SOMETHING, ERR_SOMETHING2 то всё будет отлично.
Код
switch( error)
{
case ERR_OK: делаем что-то
break;
case ERR_SOMETHING:
break;
case ERR_SOMETHING2:
break;
}

Это будет работать вне зависимости от значений энумов.

Eсли функция возвращает int а мы делаем return ERR_SOMETHING; который вообще-то Error_t - это дурной тон.
Потом чтобы обработать эту ошибку нам надо этот инт опять кастить в enum и начинается каша. Потом кто-то подставит вместо ERR_SOMETHING магическое число какое-нибудь и оно работает. Через год в энум Error_t доавбяют сверху пару новых кодов ошибок, значения все съезжают и то самое магическое число начинает указывать на другую ошибку. Начинается очень большое веселье.

Систему типов компилятора надо использовать, а не бороться с ней!


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
AnatolyT
сообщение May 26 2017, 10:25
Сообщение #20


Частый гость
**

Группа: Участник
Сообщений: 176
Регистрация: 29-03-10
Пользователь №: 56 269



Может быть чтобы не было соблазна добавить в начало enum новый код ошибки лучше однозначно закрепить код ошибки в define, потом все равно разбирать его в switch case. Другое дело если используем enum, тогда можно одновременно вести массив строк с сообщениями об ошибках, в порядке соответствующем enum, хотя тоже самое можно делать и с кодами определенными в define.

Сообщение отредактировал AnatolyT - May 26 2017, 20:04
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 26 2017, 10:58
Сообщение #21


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Может быть чтобы не было соблазна добавить в начало enum новый код ошибки лучше однозначно закрепить код ошибки в define,
Может, если в коде не будет ненужных приведений типов и магических цифр - можно доавбялть в энумы что угодно и куда угодно?

Enum - это не define. Дискутировать в плоскости enum vs define не корректно.
Так можно и до define vs template дойти.... это всё глупости.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 26 2017, 13:33
Сообщение #22


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(sigmaN @ May 26 2017, 13:10) *
Код
typedef enum{
ERR_OK,
ERR_SOMETHING,
ERR_SOMETHING2
} Error_t;

sigmaN: а почему Вы большими буквами значения енума определяете?

Сообщение отредактировал AlexRayne - May 26 2017, 13:33
Go to the top of the page
 
+Quote Post
k155la3
сообщение May 26 2017, 14:38
Сообщение #23


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

Группа: Свой
Сообщений: 1 123
Регистрация: 8-03-09
Из: Днепр
Пользователь №: 45 848



Цитата(AlexRayne @ May 26 2017, 16:33) *
sigmaN: а почему Вы большими буквами значения енума определяете?

Ну например, #def в проекте мало. А кодов на базе enum - очень много, и надо чтоб они хорошо выделялись из текста.
Если нет какой-либо корп. политики-правил, то это дело целесообразности-удобства для аффтора sm.gif
Я использую префикс eSET_MODE_RUN - с макросами уже не путаются.
IMHO.

Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 26 2017, 15:45
Сообщение #24


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
а почему Вы большими буквами значения енума определяете?
да это всё дело вкуса на самом деле... Это как раз не принципиально.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
dxp
сообщение May 27 2017, 05:21
Сообщение #25


Adept
******

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



QUOTE (sigmaN @ May 26 2017, 22:45) *
да это всё дело вкуса на самом деле... Это как раз не принципиально.

Скорее не вкуса, а стиля. Заглавными символами принято описывать неизменяемые сущности типа констант, литералов.
CODE
#define SLON 1
const uint32_t MAMONT = 10;
enum TSlon
{
    KOT = 20,
    BEGEMOT
};

...

TSlon Slon = KOT;

uint32_t x = Slon == BEGEMOT ?  MAMONT : SLON;


Сразу видно, где переменные, а где константы/литералы. Устоявшийся стиль. Стараюсь придерживаться его.


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 28 2017, 09:13
Сообщение #26


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Кстати вы заметили, как в С++11 поправили enum? Я имею ввиду enum class.
Убрали возможность неявного приведения к int, ограничили областть видимости перечислений?

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


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 28 2017, 10:26
Сообщение #27


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(k155la3 @ May 26 2017, 12:01) *
Кроме очевидных преимуществ-удобств разгружающих моск.
Если Вы определили возвр. значение с типом enum, то при работе на отладке

Enum в аргументах/результатах функций это конечно правильно и удобно в отладке, но к сожалению например IAR при работе с enum-аргументами функции вставляет в каждой операции команды расширения байт->слово.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 28 2017, 11:17
Сообщение #28


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
The enum type
The compiler will use the smallest type required to hold enum constants, preferring
signed rather than unsigned.
When IAR Systems language extensions are enabled, and in C++, the enum constants
and types can also be of the type long, unsigned long, long long, or unsigned
long long.
To make the compiler use a larger type than it would automatically use, define an enum
constant with a large enough value. For example:
/* Disables usage of the char type for enum */
enum Cards{Spade1, Spade2,
DontUseChar=257};

http://supp.iar.com/FilesPublic/UPDINFO/00...opmentGuide.pdf page 227



--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
dxp
сообщение May 28 2017, 13:02
Сообщение #29


Adept
******

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



QUOTE (sigmaN @ May 28 2017, 16:13) *
Кстати вы заметили, как в С++11 поправили enum? Я имею ввиду enum class.
Убрали возможность неявного приведения к int, ограничили областть видимости перечислений?

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

Да, улучшения налицо. Только enum class - это, я понял, как раз создание пространства имён для элементов перечисления, а тип там указывается, например, как enum EnumName : uint32_t (тип можно использовать любой целый, который подходит для хранения представления).

Жаль, что некоторые популярные компиляторы - например, IAR, - не поддерживают C++11. Или я отстал о жизни?


--------------------
«Отыщи всему начало, и ты многое поймёшь» К. Прутков
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 28 2017, 13:50
Сообщение #30


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Цитата
Только enum class - это, я понял, как раз создание пространства имён для элементов перечисления
Ну и это и плюс отсутствие неявного преобразования в int.

Код
enum class Color {RED, GREEN, BLUE};  
int i = Color::RED; //compiler error!
int i = static_cast<int>(Color::RED); //Ok


Т.е. именно более сильная типизация во всех её проявлениях.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
AlexRayne
сообщение May 29 2017, 07:42
Сообщение #31


Местный
***

Группа: Участник
Сообщений: 319
Регистрация: 27-09-07
Пользователь №: 30 877



Цитата(dxp @ May 27 2017, 09:21) *
Скорее не вкуса, а стиля. Заглавными символами принято описывать неизменяемые сущности типа констант, литералов.

Сразу видно, где переменные, а где константы/литералы. Устоявшийся стиль. Стараюсь придерживаться его.


На моем опыте старались отличать макрос от немакроса.
а вот как раз константы вполне подходит описывать как и обычные переменные, потому что на одном этапе разработки они переменные, на другом уже константы.
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 29 2017, 08:35
Сообщение #32


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(sigmaN @ May 28 2017, 13:17) *
The compiler will use the smallest type required to hold enum constants, preferring

Это всё известно и хорошо. Но, по уму, должно касаться только правил хранения этого enum. Т.е. - какого размера память выделить для его хранения. А не касательно аргументов функций передаваемых в регистрах. При передаче аргумента в регистре, он занимает весь регистр, и расширение байт->слово в таком случае - совершенно бессмысленная операция. Да ещё выполняемая перед каждым использованием значения этого enum-а.
Конечно можно сделать: int x = x_enum; в начале функции, но опять теряется удобство отладки sad.gif
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 29 2017, 08:55
Сообщение #33


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Ну тогда надо конкретизировать на примерах.
Я так понимаю, что если для энума(для его хранения как вы говорите) будет выбран тип uint8_t то и аргумент функции тоже будет uint8_t и передача аргумента этой функции должна быть выполнена по тем-же правилам, что и передача аргумента с типом uint8_t. Как-то слишком уж глупо нечто, что хранится как uint8_t передавать в функцию по правилам uint16_t...

Конкретизируем.
STM8, IAR, функция с одинм аргументом.
По правилам передачи аргументов 8ми битные передаются через регистр А, 16ти битные через регистр X
Вы утрерждаете, что enum будет передан через регистр X не смотря на то, что в памяти будет занимать 8бит.
Правильно я понял ход ваших мыслей?

Код
typedef enum{
  TEST1,
  TEST2
} testEnum_t;

volatile testEnum_t te = TEST1; //to avoid inlining and optimizations

void testF(testEnum_t enm)
{
  nop();
    
  switch(enm)
  {
  case TEST1: GPIOA->ODR = 0;
    break;
  case TEST2: GPIOA->ODR = 0xff;
    break;
  }
  nop();
}



int main()
{
  testF(te);
}


Код
   327            testF(te);
   \   000008 C6 ....      LD        A, L:te
   \   00000B 9D           NOP
   \   00000C 27 09        JREQ      L:??main_0
   \   00000E 4A           DEC       A
   \   00000F 26 0A        JRNE      L:??main_1
   \   000011 35 FF 5000   MOV       L:0x5000, #0xff
   \   000015 20 04        JRA       L:??main_1
   \                     ??main_0:
   \   000017 725F 5000    CLR       L:0x5000
   \                     ??main_1:
   \   00001B 9D           NOP


Всё замечательно, аргумент функции в виде энума использует 8ми битный регистр A ибо весь энум помещается в 8бит.

исправляем так, чтоб энум стал 16бит. Всё остальное не меняем
Код
typedef enum{
  TEST1,
  TEST2 = 1024
} testEnum_t;

компилируем....
Код
    327            testF(te);
   \   000008 CE ....      LDW       X, L:te
   \   00000B 9D           NOP
   \   00000C 27 0B        JREQ      L:??main_0
   \   00000E 1D 0400      SUBW      X, #0x400
   \   000011 26 0A        JRNE      L:??main_1
   \   000013 35 FF 5000   MOV       L:0x5000, #0xff
   \   000017 20 04        JRA       L:??main_1
   \                     ??main_0:
   \   000019 725F 5000    CLR       L:0x5000
   \                     ??main_1:
   \   00001D 9D           NOP

используется регистр X.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post
jcxz
сообщение May 29 2017, 09:34
Сообщение #34


Гуру
******

Группа: Свой
Сообщений: 5 228
Регистрация: 3-07-08
Из: Омск
Пользователь №: 38 713



Цитата(sigmaN @ May 29 2017, 10:55) *
Я так понимаю, что если для энума(для его хранения как вы говорите) будет выбран тип uint8_t то и аргумент функции тоже будет uint8_t и передача аргумента этой функции должна быть выполнена по тем-же правилам, что и передача аргумента с типом uint8_t. Как-то слишком уж глупо нечто, что хранится как uint8_t передавать в функцию по правилам uint16_t...

Глупо - это если сказано про расширение размера данных не понимать, что речь естественно идёт не о 8-битной архитектуре. Я говорил про 32-битный IAR for ARM.
И я написал: аргумент функции типа enum, а не u8 или u16.
Go to the top of the page
 
+Quote Post
sigmaN
сообщение May 29 2017, 10:10
Сообщение #35


I WANT TO BELIEVE
******

Группа: Свой
Сообщений: 2 617
Регистрация: 9-03-08
Пользователь №: 35 751



Вот и я гворю: уточнять надо. Кто куда и кого расширяет.

Пока, кстати, не видно разницы между аргументами i8 i16 i32 и энумами с соответствующими размерами.... Но IAR для ARM у меня под рукой нет.


--------------------
The truth is out there...
Go to the top of the page
 
+Quote Post

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

 


RSS Текстовая версия Сейчас: 3rd August 2025 - 14:53
Рейтинг@Mail.ru


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