3

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?

Paul R
  • 208,748
  • 37
  • 389
  • 560
PICyourBrain
  • 9,976
  • 26
  • 91
  • 136

4 Answers4

14

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
  • 510,854
  • 105
  • 1,084
  • 1,005
  • Sorry I didn't mention it but I do have a prototype that matches what I have above... – PICyourBrain Mar 10 '10 at 19:13
  • 1
    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 Mar 10 '10 at 19:27
  • 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*. – AnT stands with Russia Mar 10 '10 at 19:34
  • 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? – PICyourBrain Mar 10 '10 at 19:53
  • @Jordan: `ret_name->Name[0] = '@';` – kennytm Mar 10 '10 at 20:00
  • 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" – PICyourBrain Mar 10 '10 at 20:16
  • @Jordan: Ask in a new question. – kennytm Mar 10 '10 at 20:17
  • 1
    +1 for passing in a pointer to the structure instead of returning a huge struct. – cschol Mar 19 '10 at 13:02
6

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.

AnT stands with Russia
  • 312,472
  • 42
  • 525
  • 765
  • Sorry, you are wrong. K&R compilers, at least all the ones I've ever used, return structures by value. –  Mar 10 '10 at 19:16
  • 1
    @Neil Butterworth: Whatever you used, implemented struct assignment as an extension. The "canonical" K&R C does not allow struct assigment and struct-passing/returning by value. http://en.wikipedia.org/wiki/C_(programming_language)#K.26R_C – AnT stands with Russia Mar 10 '10 at 19:19
  • @AndreyT A reference, please. –  Mar 10 '10 at 19:20
  • @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) – AnT stands with Russia Mar 10 '10 at 19:21
  • @AndreyT Fair enough, I guess all the pre-ANSI compilers I used were from "AT&T and some other vendors". I lost my copy of K&R first ed many years ago, so can't easily look at what it says. –  Mar 10 '10 at 19:24
1

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
  • 4,769
  • 29
  • 33
0

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;
}
  • 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? – PICyourBrain Mar 10 '10 at 20:16
  • @Jordan I think maybe the time has come to sit down and read your compiler and linker's manual. The hardware & software you are using would appear to be so far from being standard that asking further questions here may not get you very far, –  Mar 10 '10 at 20:32