8 бит тип enum в C
Я должен хранить инструкции, команды, которые я буду получать через последовательный канал. Команды будут иметь длину 8 бит.
Мне нужно сохранить прозрачность между именем команды и ее значением. Чтобы избежать необходимости перевода 8-битного числа, полученного в последовательном режиме, в любой тип.
Я хотел бы использовать перечисления для работы с ними в моем коде. Только перечисление соответствует на этой платформе 16-битному целому числу.
Платформой является микроконтроллер AVR ATmega169V, на демонстрационная доска Butterfly . Это 8-битная система с некоторой ограниченной поддержкой 16-битных операций. Это не быстрая система и имеет около 1 Кб оперативной памяти. В нем нет никаких предметов роскоши, таких как файловый ввод/вывод или операционная система.
Итак, какие предложения относительно того, какой тип я должен использовать для хранения 8-битных команд?
Должно быть что-то получше, чем массивный заголовок #defines.
6 ответов:
gcc
's-fshort-enums
может быть полезно:Выделять типу "enum" только как много байт, как это необходимо для объявленный диапазон возможных значений. В частности, тип "перечисление" будет эквивалентный наименьший целочисленный тип, в котором достаточно места.
На самом деле, здесь Страница с большим количеством соответствующей информации. Я надеюсь, что вы столкнетесь со многими коммутаторами GCC, о существовании которых вы и не подозревали. ;)
Вы пытаетесь решить проблему, которой не существует.
Ваш вопрос помечен C. В языке C типы enum в контексте значений полностью совместимы с целочисленными типами и ведут себя так же, как и другие целочисленные типы. При использовании в выражениях они подвергаются точно такому же интегральному продвижению, как и другие интегральные типы. Как только вы это учтете, вы должны понять, что если вы хотите хранить значения, описываемые константами перечисления в 8-битном целочисленном типе, все, что вам нужно do-это выбрать подходящий универсальный 8-битный интегральный тип (скажем
int8_t
) и использовать его вместо типа enum. Вы ничего не потеряете, если будете хранить значения констант enum в объекте типаint8_t
(в отличие от объекта, явно объявленного с типом enum).Проблема, которую вы описываете, существовала бы в C++, где типы enum отделены гораздо дальше от других интегральных типов. В C++ использование интегрального типа вместо перечислительного типа с целью экономии памяти является более сложным (хотя вероятный). Но не в С,где это не требует никаких дополнительных усилий.
Я не понимаю, почему перечисление не работает. Сравнения с перечислением и назначения из него должны работать нормально с расширением по умолчанию. Просто будьте осторожны, чтобы ваши 8-битные значения были подписаны правильно (я думаю, что вы хотели бы беззнаковое расширение).
Вы получите 16-битные сравнения таким образом, я надеюсь, что это не будет проблемой производительности (это не должно быть, особенно если ваш процессор 16-битный, как это звучит).
Компилятор Microsoft C позволяет сделать что-то вроде этого, но это расширение (оно стандартно в C++0x):
enum Foo : unsigned char { blah = 0, blargh = 1 };
Поскольку вы отметили GCC, я не совсем уверен, возможно ли то же самое, но GCC может иметь расширение в режиме
gnu99
или что-то для него. Дайте ему шанс.
Я бы рекомендовал остановиться на перечислении в любом случае по следующим причинам:
- это решение позволяет вам сопоставлять значения команд непосредственно с тем, что ожидает ваш последовательный протокол.
- Если вы действительно используете 16-битную архитектуру, то есть не так много преимуществ, чтобы перейти к 8-битному типу. Думать о других аспектах, то 1 байт памяти.
- в некоторых компиляторах я использовал фактический размер перечисления, использовал минимальное количество битов (перечисления, которые могли бы поместиться в байт, использовали только байт, затем 16 бит, затем 32).
Во-первых, вы не должны заботиться о реальной ширине типа. Только если вам действительно нужен эффективный способ хранения, вы должны использовать флаги компилятора, такие как-fshort-enums на компиляторе GNU, но я не рекомендую их, если они вам действительно не нужны.
В качестве последней опции вы можете определить 'enum' как данные представления для команд и использовать преобразование в байт с помощью 2 простых операций для хранения / восстановления значения команды в / из памяти (и инкапсулировать это в одном месте). А как насчет этого? Это очень важно. простые операции, так что вы можете даже встроить их (но это позволяет вам действительно использовать только 1 байт для хранения и с другой стороны выполнять операции, используя наиболее удобный enum, определенный как вам нравится.
Ответ, который имеет отношение к компилятору ARC (Цитируется по DesignWare MetaWare C / C++ Programmer's Guide for ARC; раздел 11.2.9.2)
Размер перечислений размер типа enum зависит от состояния переключателя *Long_enums*.
■ если переключатель * Long_enums * выключен, тип перечисления сопоставляется с наименьшим из одного, двух или четырех байтов, так что все значения могут быть представлены.
■ если переключатель * Long_enums * включен, перечисление сопоставляется с четыре байта (совпадение соглашение о компиляторе AT&T Portable C).