0

I am having a compiler issue in Visual Studio 2005 using the standard C compiler when trying to do a structure copy from one location to another.

The types are defined in a file as follows:

definition.h

#define MAX 7

typedef struct{
   char    recordtext[18];
   boolean recordvalid;
}recordtype;

typdef recordtype tabletype[MAX];

typedef struct{
   tabletype table;
}global_s;

Let us pretend that a global_s "object" is instantiated and initialized somewhere and a pointer to this structure is created.

#include "definition.h"

global_s global;
global_s* pglobal = &global;
init(&pglobal);

Meanwhile, in another file (and this is where my problem is) i am trying to create a local tabletype object, and fill it with the global table member, using a get method to protect the global (lets pretend it is "static")

#include "definition.h"

extern global_s* pglobal;

tabletype t;
gettable(&t);

void gettabl (tabletype* pt)
{
   *pt = pglobal->table;
}

When I go to compile, the line in the gettable function throws a compiler error "error C2106: '=': left operand must be l-value. It looks as though this should behave as a normal copy operation, and in fact if I perform a similar operation on a more basic structure I do not get the error. For example If I copy a structure only containing two integers.

Does anyone have a solid explanation as to why this operation seems to be incorrect?

(Disclaimer: I have developed this code as a scrubbed version of my actual code for example purposes so it may not be 100% correct syntactically, I will edit the question if anyone points out an issue or something needs to be clarified.)

2 Answers2

0

It's the arrays in the struct; they cannot be assigned. You should define an operator=() for each of the structs, and use memcpy on the arrays, or copy them in a loop element by element.

Realz Slaw
  • 3,138
  • 1
  • 24
  • 38
0

(IF you want to get a reference to your global variable):

I am not sure, if this is correct (and the problem), but I think besides function prototypes, arrays and pointers (to arrays 1. element) are NOT exactly the same thing. And there is a difference between pointer to array and pointer to the 1. element of an array)

Maybe taking the adress of the array:

*pt = &(pglobal->table);

Anyway it might be better not to fetch the address of the whole array but the address of the first element, so that the resulting pointer can be used directly as record array (without dereferencing it)

recordtype* gettable (size_t* puLength)
{     
    *puLength = MAX;     
    return &(pglobal->table[0]);        
}

(IF you want a copy of the table):

Arrays can't be copied inplace in C90, and of course you have to provide target memory. You would then define a function get table like this:

void gettable (recordtype * const targetArr)
{
    size_t i = 0;
    for (; i < MAX; i++) targetArr[i] = pglobal->table[i];
    return;
}

an fully equivalent function prototype for gettable is:

void gettable(recordtype[] targetArr);

Arrays are provided by refernce as pointer to the first element, when it comes to function parameters. You could again ask for an pointer to the whole array, and dereference it inside gettable. But you always have to copy elementwise.

You can use memcopy to do the job as 1-liner. Modern compilers should generate equally efficent code AFAIK.

Mark A.
  • 579
  • 4
  • 13