Массив структур — ошибки инициализации

Я создаю здесь некоторые структуры данных (с помощью MFC), компилирую в MS Visual C++ 6.0 (да, он старый).

struct SOpcodeData
{
    BYTE m_byDataType;
    DWORD m_dwMinValue;
    DWORD m_dwMaxValue;
    WORD m_wRepeat;
};

const BYTE DATA_U8   = 0;
const BYTE DATA_U16  = 1;
const BYTE DATA_U32  = 2;

SOpcodeData MY_BYTE  = { DATA_U8,   0,  UCHAR_MAX,  1 };
SOpcodeData MY_WORD  = { DATA_U16,  0,  USHRT_MAX,  1 };
SOpcodeData MY_DWORD = { DATA_U32,  0,  UINT_MAX,   1 };

Этот код компилируется без ошибок или предупреждений. Но когда я пытаюсь создать массив моего типа структуры...

SOpcodeData foo[] = { MY_BYTE, MY_BYTE, MY_WORD, MY_DWORD, MY_BYTE };

VC6 выдает ошибку компиляции для каждого элемента массива:

device.cpp(78): ошибка C2440: «инициализация»: невозможно преобразовать «struct SOpcodeData» в «unsigned char»

Нет доступного пользовательского оператора преобразования, который может выполнить это преобразование, или оператор не может быть вызван

Очевидно, он ошибочно принимает весь тип структуры за первое поле структуры, которое является BYTE (или unsigned char для тех, кто не привык к MFC).

Пробовал на Visual Studio 2010, работает отлично. Но мне нужно построить его с помощью VC6.

Я пытался явно привести тип структуры к типу структуры внутри инициализации массива, но это избыточно и ничего не решает. Любые другие идеи?


person Taschetto    schedule 19.07.2012    source источник


Ответы (2)


Поскольку вы настаиваете на использовании компилятора с множеством известных ошибок, вам понадобится уродливый обходной путь:

#define MY_BYTE_CONTENT  { DATA_U8,   0,  UCHAR_MAX,  1 }
#define MY_WORD_CONTENT  { DATA_U16,  0,  USHRT_MAX,  1 }
#define MY_DWORD_CONTENT { DATA_U32,  0,  UINT_MAX,   1 }

SOpcodeData MY_BYTE  = MY_BYTE_CONTENT;
SOpcodeData MY_WORD  = MY_WORD_CONTENT;
SOpcodeData MY_DWORD = MY_DWORD_CONTENT;

SOpcodeData foo[] = { MY_BYTE_CONTENT, MY_BYTE_CONTENT, MY_WORD_CONTENT, MY_DWORD_CONTENT, MY_BYTE_CONTENT };
person Ben Voigt    schedule 19.07.2012
comment
Спасибо! Это сработало. Идеальная компиляция. :-) Лично я бы не стал компилировать на VC6, но приходится. С уважением! - person Taschetto; 19.07.2012
comment
Этот обходной путь должен быть эффективным, но я не думаю, что это ошибка — списки инициализаторов массивов обычно не принимают другие переменные для инициализации элементов массива, за исключением, возможно, встроенных типов (и это может быть просто общим расширением — я не помню, что об этом говорится в стандартах, поэтому могу ошибаться). - person twalberg; 19.07.2012
comment
Я тоже не знаю о стандартах, но инициализация массива с не встроенными типами отлично работает в Visual Studio 2010. - person Taschetto; 19.07.2012
comment
@twalberg: я думаю, ты ошибаешься на 100%. Существуют ограничения на инициализаторы, если вы хотите использовать результирующую переменную в контексте, который требует константного интегрального выражения времени компиляции (например, в качестве границ в типе массива), но в общем случае инициализация может быть любым допустимым выражением, и поэтому могут быть частями агрегатного инициализатора. - person Ben Voigt; 19.07.2012

Мы нашли другое решение без использования #define: использование конструктора для инициализации структур данных. Типа вот так:

struct SOpcodeData
{
    SOpcodeData (const BYTE byDataType, const DWORD dwMinValue, const DWORD dwMaxValue, const WORD wRepeat)
      : m_byDataType(byDataType), m_dwMinValue(dwMinValue), m_dwMaxValue(dwMaxValue), m_wRepeat(wRepeat)
    {}

    BYTE m_byDataType;
    DWORD m_dwMinValue;
    DWORD m_dwMaxValue;
    WORD m_wRepeat;
};

SOpcodeData MY_BYTE  (DATA_U8,   0,  UCHAR_MAX,  1);
SOpcodeData MY_WORD  (DATA_U16,  0,  USHRT_MAX,  1);
SOpcodeData MY_DWORD (DATA_U32,  0,  UINT_MAX,   1);

SOpcodeData foo[] = { MY_BYTE, MY_WORD, MY_DWORD };

Спасибо всем!

person Taschetto    schedule 19.07.2012