4

I'm creating some data structures here (with MFC), compiling in MS Visual C++ 6.0 (yes, it's old).

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 };

This code compiles with no errors or warnings. But when I try to create an array of my struct type...

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

VC6 pops a compilation error for each array element:

device.cpp(78) : error C2440: 'initializing' : cannot convert from 'struct SOpcodeData' to 'unsigned char'

No user-defined-conversion operator available that can perform this conversion, or the operator cannot be called

Aparently it is mistaking the whole struct type with the first struct field, which is a BYTE (or unsigned char for those who are not used to MFC).

Tried it on Visual Studio 2010 and it works perfectly. But I need to build it using VC6.

I've tried to explicit cast to struct type inside array initialization, but that's redundant and does not solved anything. Any other ideas?

2 Answers 2

4

Since you insist on using a compiler with lots and lots of known bugs, you will need an ugly workaround:

#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 };
Sign up to request clarification or add additional context in comments.

4 Comments

Thank you! It worked out. Perfect compilation. :-) Personally I wouldn't be compiling on VC6, but I have to. Regards!
That workaround should be effective, but I don't think this is a bug - array initializer lists generally don't accept other variables to initialize array elements, except maybe for built-in types (and that may just be a common extension - I don't recall what the standard(s) have to say about that, so I may be mistaken).
I don't know about the standards either, but array initialization with non-built-in types works just fine in Visual Studio 2010.
@twalberg: I think you're 100% mistaken. There are restrictions on initializers if you want to use the resultant variable in a context that requires a compile-time constant integral expression (for example, as the bounds in an array type), but initialization can in general be any valid expression, and so can the parts of an aggregate initializer.
0

We've figured out another solution, without using #define: using a constructor to initialize the data structures. Sorta like this:

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 };

Thanks to everyone!

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.