This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Assigning structures in C++



Hello All!

Usually I develop embedded code using C-code without any C++ files.
Nevertheless recently I've decided to use C++.
I don't need classes, overloading, etc., - just some basic C++ features like namespaces and pointers to the type defined later (for linked lists).

Now I have an issue which I'd like to fix:
C++ doesn't allow me to assign one structure to another.

For example:

typedef struct t_struct { int a; } t_struct;
t_struct b, c;
b.a = 1;
a = b; // error! don't know how to assign...

The same code is successfully compiled by a Microsoft compiler.
In addition it is successfully compiled if using C instead of C++. 

I'm using C6000 compiler v.6.1 but I think it may be a common issue for TI's compiler.

I suppose that TI's compiler considers structures as C++ structures (with member-functions) but doesn't generate default copying constructors.
Thus it cannot assign structures even if they're of the same type.

Right now I overcome this problem by manual copying of the separate structure fields, but it isn't convenient and may be dangerous if structure type is changed.

Is it possible to make C++ consider a structure as C-structure, or to make it generate copying constructor correctly?

  • The TI compiler handles struct assigns correctly even in C++, and it does generate the required default copy constructors when appropriate.  Are you sure "a" is declared to have the same struct type as "b"?  When I declare "a" to be of type "t_struct", this example compiles without an error.

  • Yes, I'm sure that the types were the same. More than that compiler itself 'told' that in its diagnostic message.
    At first I thought that 'volatile' modifier may matter because in C I had a code which may be expressed as:

    volatile t_struct a;
    void * b;
    t_struct c;
    c.a = 1;
    b = &c;
    a = *(t_struct*)b;

    First of all I've checked if the structures without 'volatile' can be assigned and they couldn't :(
    If the same file's extention is changed from .cpp to .c it is compiled as usual.

    Are you sure we're using the same compiler?
    Is it possible that compilation options matters?

    I used no specific compilation keys, just includes, several definitions, and debugging enabled.

  • Vladislav Vasiliev said:
    volatile t_struct a;

    Aha!  That's the problem.  Yes, volatile is the problem here.  The exact error message emitted by the TI compiler is:

    "vv.cpp", line 19: error: no operator "=" matches these operands operand types are: volatile t_struct = t_struct

    The error message from GNU g++ is different:

    vv.cpp:19: error: passing 'volatile t_struct' as 'this' argument of 't_struct& t_struct::operator=(const t_struct&)' discards qualifiers

    Basically, the problem is that the volatile copy constructor is not one of the several constructors the compiler is allowed to create automatically.  You can get around this problem by using the C++ idiom for initialization:

    volatile t_struct a(b);

    This is just one of the many small incompatibilities between C and C++, and not a bug in the TI compiler.  The Microsoft compiler apparently supports it as an extension.

    Vladislav Vasiliev said:
    Are you sure we're using the same compiler?
    Is it possible that compilation options matters?

    Since the original post didn't have a compilable test case, I had to fill in some details by guessing.  I created a valid test case that did not reflect the code you were having a problem with.  This is why we usually request a compete, compilable test case and the verbatim text of the error message.

  • Hi again!

    Actually, as I told, I've checked different codes: both with 'volatile' and without it, and I couldn't get them compiled in both cases :(

    I'm at home now, so it is possible to test all once again only tomorrow.
    I'll report about the results, once I get them.

    Anyway, thanks for your response.

  • Hi Archaeologist!

    Thanks a lot for your time and the correct answer!
    It looks like 'volatile' was actually a problem. 

    Archaeologist said:

    You can get around this problem by using the C++ idiom for initialization:
    volatile t_struct a(b);

    Unfortunately I cannot use this solution, because t_struct is a field of a complex static volatile structure used as a driver descriptor (that's why it's volatile).
    The only two solutions I see now are either to use field-by-field copying (or memcpy), or to use .c-file.
    I hoped to have the same (my) namespace for my functions, so it looks like I have to use the first case.

    Actually, I've made another mistake while preparing test case for structure copying.
    Instead of using 'typedef struct t_struct' and then creating two 't_struct' variables, I used two structures with the same fields.
    Thus they were not of the same 'type' from compiler's point of view, and couldn't be copied.
    For me it was strange that C file was compiled and C++ wasn't :)

    I've missed again, that in C++ structures are copied by copying constructor instead of field-by-field assigning, and thus they should be of the same type or at least to have explicit copying constructor defined.

    By defining different 'untyped' structures, I've made them to have undefined copying constructor and C++ failed to build anything.

    Archaeologist said:
    Since the original post didn't have a compilable test case, I had to fill in some details by guessing.  I created a valid test case that did not reflect the code you were having a problem with.  This is why we usually request a compete, compilable test case and the verbatim text of the error message.

    Unfortunately I have no Internet access on my working PC, so it was a problem to 'copy-paste' exact error message (at least to do it fast). Thus I've tried to reproduce it in my own words.
    Sorry for that. Next time I'll spend more time to prepare a fully correct request.