tags:

views:

325

answers:

4

I am working on a program in C and using the SDCC compiler for a 8051 architecture device. I am trying to write a function called GetName that will read 8 characters from Flash Memory and return the character array in some form. I know that it is not possible to return an array in C so I am trying to do it using a struct like this:

//********************FLASH.h file*******************************
MyStruct GetName(int i);  //Function prototype

#define NAME_SIZE  8

typedef struct
{
    char Name[NAME_SIZE];
} MyStruct;

extern MyStruct GetName(int i);


// *****************FLASH.c file***********************************
#include "FLASH.h"

MyStruct GetName( int i)
{
     MyStruct newNameStruct;

     //...
     // Fill the array by reading data from Flash 
     //...

     return newNameStruct;
}

I don't have any references to this function yet but for some reason, I get a compiler error that says "Function cannot return aggregate." Does this mean that my compiler does not support functions that return structs? Or am I just doing something wrong?

+11  A: 

SDCC doesn't support assignment and returning structs yet (if their Wiki is up-to-date):

Not yet implemented in sdcc:

  • Data type double.
  • Structures and unions can not be assigned, passed as function parameters or return values.
  • register storage class specifier in function parameters.

Maybe you should make a

void GetName(MyStruct* ret_name, int i);

function instead.


That said, you should put the function prototype before the main and after the MyStruct. If there's no prototypes a function will be assumed to return int.

MyStruct GetName(int i);
void main(void) { ...

(Also, the main function should be an int main(void) or int main(int argc, char** argv). It shouldn't return void.)

KennyTM
Sorry I didn't mention it but I do have a prototype that matches what I have above...
Jordan S
@Jordan: Please show the complete code then.
KennyTM
I'm using the SDCC compiler
Jordan S
That still can't be the proper complete code, since the definition of MyStruct appears after the prototype, which would not compile. Order *matters* here. Show us *exactly* what you are trying to compile.
Tyler McHenry
The claim about prototype is not exactly correct. In this case the OP might easily get away with a non-prototype declaration `MyStruct GetName()`. The compiler will *not* assume that it returns an `int`, even though it has no prototype. Actually, most of the post incorrectly uses the term *prototype* in place the term *declaration*.
AndreyT
I tried your suggestion of using void GetName(MyStruct* ret_name, int i); How do I assign a value to the array in ret_name?
Jordan S
@Jordan: `ret_name->Name[0] = '@';`
KennyTM
ok that worked, now I am getting a linker error that says "?ASlink-Error-Could not get 29 consecutive bytes in internal RAM for area DSEG"
Jordan S
@Jordan: Ask in a new question.
KennyTM
+1 for passing in a pointer to the structure instead of returning a huge struct.
cschol
+6  A: 

All post-ANSI C89/90 compilers allow returning struct objects. Classic (pedantic) K&R C compilers do not.

However, in any case you have to declare the function first. i.e. before you call it. And char[8] Name inside your struct is not a valid declaration. The valid form is char Name[8].

Your pointer-to-array-returning function is declared correctly. It is your size macro that's broken. Should be

#define NAME_SIZE 8 

Note: no = character.

AndreyT
anon
Ok, I changed it to char Name[8] and still no luck...
Jordan S
AndreyT
@AndreyT A reference, please.
anon
@Neil Butterworth: I hope this will do http://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C (see at the end of the section)
AndreyT
anon
+1  A: 

Yes, functions can return structs in C. Your code above has several errors. With a few changes, It compiles correctly under gcc (I don't have sdcc installed to try with, but please try the code below.

 struct MyStruct
 {
   char Name[8];
 }; 

 struct MyStruct GetName( int i)
 {
      struct MyStruct newNameStruct;

      //...
      // Fill the array by reading data from Flash 
      //...
     return newNameStruct;
 } 


 int main(void)
 {
     int NameIndex = 3;
     struct MyStruct testStruct;
     testStruct = GetName(NameIndex);
     return 0;  
 }
bdk
A: 

I really wouldn't want to use a C compiler that didn't implement structure call and return by value, as KennyMT suggests yours doesn't. In fact, such a compiler should not really be called a C compiler. If the compiler implements structures at all, return by value is not hard to implement.

Anyway, to work with your compiler you will want something like:

typedef struct
{
    char Name[NAME_SIZE];
} MyStruct;

void f( MyStruct * m ) {
   strcpy( m->Name, "foo" );
}

int main() {
    MyStruct ms;
    f( & ms );
    return 0;
}
anon
OK, I tried this and now I get a linker error saying that "?ASlink-Error-Could not get 29 consecutive bytes in internal RAM for area DSEG" What is DESG?
Jordan S
anon
probably right...
Jordan S