Home > Software engineering >  Can you return a struct that is declared inside that function?
Can you return a struct that is declared inside that function?

Time:11-26

I want to return the struct that is declared, and values set inside the initializePlayer() function so I can call it on the main function.
This is a task and we are not allowed to declare global variables (only inside of functions) so I kind of think that I need to declare the struct inside functions—unless it's not a variable(?) I don't really know :(

Here is my code and I can't get it to work

struct Player initializePlayer(int playerNumber)
{
    struct Player
    {
        int position[1][2];
        double money;
        int propertiesOwned[10];
    } player[4];

    // Set player's position to starting tile
    player[playerNumber].position[0][0] = 5;
    player[playerNumber].position[0][1] = 0;
    // Set player's default money
    player[playerNumber].money = 300000;
    // Set player's properties to none
    for (int i; i <= 10; i  )
    {
        player[playerNumber].propertiesOwned[i] = 0;
    }
    // Player initialized

    return player[playerNumber];
}

int main()
{
    // Initializes player 1 and 2
    struct Player p1 = initializePlayer(1);
    struct Player p2 = initializePlayer(2);
    return 0;
}

If I declare the struct to global however, it works just fine.

I want the function to return a struct, on which that struct is declared inside that function

CodePudding user response:

This is a task and we are not allowed to declare global variables (only inside of functions)

Type specifiers are not variables.

You need to declare a structure before its using.

Also in a function definition the return type shall be a complete object type. From the C Standard (6.9.1 Function definitions)

3 The return type of a function shall be void or a complete object type other than array type.

So this function definition

struct Player initializePlayer(int playerNumber)
{
    struct Player
    {
        int position[1][2];
        double money;
        int propertiesOwned[10];
    } player[4];
    //...

is wrong. The return type of the function is not a complete object type.

You need to define the structure before the function definition like

    struct Player
    {
        int position[1][2];
        double money;
        int propertiesOwned[10];
    };

Also it is better to pass to the function an object of the structure type by reference through a pointer to it.

In this case the function declaration will look like

void initializePlayer( struct Player *player )
{
    // Set player's position to starting tile
    player->position[0][0] = 5;
    player->position[0][1] = 0;
    // and so on

The function return type will be void.

And the array of objects of the structure type will be declared in main

int main( void )
{
    struct Player player[4] = { 0 };

    // Initializes player 1 and 2
    initializePlayer( &player[1] );
    initializePlayer( &player[2] );

    return 0;
}

CodePudding user response:

Yes you can return a struct. What you can't do is return a pointer to something that has ceased to exist in between. But that is not what you are doing here. The struct data is copied to the caller here.

Your definition of that struct, on the other hand is quite strange. It should be done before any usage. And I don't see why you would put that definition inside the function.

Just to prove my point, one example (with different simpler Player definition)

#include <stdio.h>

struct Player {
    int pos;
    char name[10];
};

struct Player f(){
    struct Player player;
    sprintf(player.name, "John");
    player.pos=12;
    printf("addr of f's local player: %p\n", &player);
    return player;
}

struct Player g(){
    struct Player player;
    player.pos=1;
    sprintf(player.name, "xxxxxxxxx");
    printf("addr of g's local player: %p\n", &player);
    return player;
}

int main(void) {

    struct Player p;
    p=f();
    struct Player q=g();
    printf("%s %d\n", p.name, p.pos);

  return 0;

On my computer, it prints

addr of f's local player: 0x7ffec7aa8ae0
addr of g's local player: 0x7ffec7aa8ae0
John 12

The points here is that you see that, in main, p.name and p.pos are indeed as they were set in f. And since g has been called in between, that g put something else in its local variable player, and since you see that (this is not a sure thing, but it was predictible, and it happened as I wanted to prove my point) local variable player of f and g has the exact same address, you know that what ever was in f's local player has been destroyed between the time we got f result and the time we print it.

And nevertheless, we got the content right.

Because f returned a copy of its local player.

So, yes, you can return struct.

That is still a tricky thing, tho, because of course if that struct itself contains pointers to some local variables, then those pointers are not valid anymore. But in your usage (once you correct the place where you define struct Player, and the strange [1] array), no such problem. What is returned is a copy.

CodePudding user response:

You try to use struct player before it is even defined. You cannot do this, you need to define the struct before.

You want this, which is the usual, standard and perfectly correct way:

// declare the struct (this does not declare a global variable)

struct Player
{
  int position[1][2];
  double money;
  int propertiesOwned[10];
};


// Now you can use it 
struct Player initializePlayer(int playerNumber)
{
  struct Player player[4];

There is also another problem:

for (int i; i <= 10; i  )

This is wrong, you forgot to initialize i.

for (int i = 0; i <= 10; i  )

There may be other errors elsewhere, I didn't check everything.

  • Related