Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > IAR С99 Инициализация полей union


Автор: LeonidPr 13.10.2015, 14:11
Добрый день всем. Возник такой вопрос.
есть вот такие типы
Код

typedef union {
  struct {
    int32_t i_max_value;
    int32_t i_min_value;
  };
  struct {
    uint32_t ui_max_value;
    uint32_t ui_min_value;
  };
  struct {
    float f_max_value;
    float f_min_value;
  };
} range_t;

typedef struct {
  set_type_t mi_type; 
  uint8_t *mi_ptr;
  range_t mi_range;
} map_item_t;

где set_type_t это просто перечисление.
Теперь мне нужно создать переменную типа map_item_t и проинициализировать её при объявлении.
Код

map_item_t item = {set_type_bool, 0, {i_min_value:0,i_max_value:0}};

Компилятор ругается, что i_min_value, i_max_value не определены. Если писать по другому
Код

map_item_t item = {set_type_bool, 0, {0, 0}};

то все компилируется, но... я хотел бы явно указывать какие поля union я инициализирую. Причем компилируется и такой вариант:
Код

map_item_t item = {set_type_float, 0, {0.9f, 0.5f}};

Могу ли я быть уверен, что компилятор не приведет 0.5f к uint32_t например и не получит 0? и второй вопрос, почему явное указание полей не работает, хотя структуры внутри union анонимные, вроде как должен такой синтаксис работать.

Автор: volatile 13.10.2015, 15:45
Цитата(LeonidPr @  13.10.2015,  14:11 Найти цитируемый пост)
Могу ли я быть уверен, что компилятор не приведет 0.5f к uint32_t например и не получит 0? 

а так не работает?
Код

map_item_t item = {x, y, .mi_range.f_max_value=.5, .mi_range.f_min_value=.42};

Автор: feodorv 13.10.2015, 15:52
Цитата(LeonidPr @  13.10.2015,  14:11 Найти цитируемый пост)
Компилятор ругается, что i_min_value, i_max_value не определены

Как-то это иначе делается, http://en.cppreference.com/w/c/language/struct_initialization.


Цитата(LeonidPr @  13.10.2015,  14:11 Найти цитируемый пост)
Могу ли я быть уверен, что компилятор не приведет 0.5f к uint32_t например и не получит 0?

По умолчанию инициализируется первый член объединения. Проведите эксперимент:
Код

typedef union {
  struct {
    int32_t i_max_value;
    int32_t i_min_value;
  };
  struct {
    uint32_t ui_max_value;
    uint32_t ui_min_value;
  };
  struct {
    float f_max_value;
    float f_min_value;
  };
} range_t;

typedef struct {
  int mi_type;
  unsigned char *mi_ptr;
  range_t mi_range;
} map_item_t;

int main( void )
{
  map_item_t item = { 1, 0, {0.9f, 0.5f} };
  printf( "imax = %d, imin = %d\n", item.mi_range.i_max_value, item.mi_range.i_min_value);
  printf( "fmax = %f, fmin = %f\n", item.mi_range.f_max_value, item.mi_range.f_min_value);
  return 0;
}

Получите нули, как и должно быть.

Добавлено через 49 секунд
Пока писал ответ, не видел ответа volatile)))

Автор: volatile 13.10.2015, 15:58
вот здесь, вроде пашет
https://ideone.com/3Uif9u
 smile 

Автор: LeonidPr 13.10.2015, 16:40
да, Volatile, действительно ваш вариант работает и с IAR компилятором. Спасибо! Сейчас буду искать, как это объясняется с точки зрения стандарта. Похоже, что как-бы резервируется место под mi_range и потом идет обращение к полям уже созданной структуры. Так-то вроде понятно, но я вряд ли бы в ближайшее время дошел до такого варианта!

Автор: volatile 14.10.2015, 09:03
Цитата(LeonidPr @  13.10.2015,  16:40 Найти цитируемый пост)
буду искать, как это объясняется с точки зрения стандарта. 


Цитата(ISO/IEC 9899:1999)

6.7.8 Initialization
...
  7 If a designator has the form .identifier
    then the current object (defined below) shall have structure or union type and the
    identifier shall be the name of a member of that type.
...
  EXAMPLE 10 Structure members can be initialized to nonzero values without depending on their order:
  div_t answer = { .quot = 2, .rem = -1 };

Автор: LeonidPr 14.10.2015, 09:39
да, то же нашел. Только вот думал, откуда я вариант с двоеточиями взял, в голове сидит ведь. Сейчас вот нашел
http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html
Цитата

Another syntax that has the same meaning, obsolete since GCC 2.5, is ‘fieldname:’, as shown here: 
Код

struct point p = { y: yvalue, x: xvalue };


Устаревший оказывается. 

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)