1

When using structs in functions, I have come along with two ways of passing them as arguments, and I don't know which one is better to use.

#include <stdio.h>

typedef struct Person{
    int age;
    int id;
} person;

static void foo(person *p1);

int main()
{
    person per1;
    person per2[1];

    foo(&per1); /*1*/
    foo(per2); /*2*/

    printf("per1. Age: %i; id: %i\n",per1.age,per1.id);
    printf("per2. Age: %i; id: %i\n",per2->age,per2->id);

    return 0;
}
static void foo(person *p1)
{
    p1->age=10;
    p1->id=123;
}

The use case is for only one instance of the struct. If no more than one is needed, which one is better, in terms of performance and sense of usage, passing the address of the generic struct declaration, or passing a unitary array of the struct that will decay to a pointer?

EUS
  • 422
  • 3
  • 16
  • 1
    `foo(&per1);` works just fine. If you need only one instance, why'd you create an array? – Sourav Ghosh May 21 '19 at 07:58
  • 1
    When you do this `printf("per2. Age: %i; id: %i\n",per2->age,per2->id);` accessing array as pointer is really confusing also disadvantage of option 2. – kiran Biradar May 21 '19 at 08:00
  • `which one is better` - in what way? They are different things. You can also do `person *per3 = &(person){}`, which is the same, and still staves you from typing `&` in front when calling functions. – KamilCuk May 21 '19 at 08:02
  • I was mainly concerned about performance, and if any of the uses had maybe little sense to use. I'm updating the post to clarify it. Thanks! – EUS May 21 '19 at 08:05
  • If you declare an `array[1]` then do use `array[0]`, mostly. The `per2->age` looks evil. – Antti Haapala -- Слава Україні May 21 '19 at 09:43

2 Answers2

8

Any modern compiler will produce identical machine code in each case, so there is no performance concern. (See Godbolt).

Since there is no performance difference, do it the way that best expresses your intent. Your intent is to have one object, and pass the address of that one object to your function. So just do that (i.e., your first option). Creating a 1-element array for no reason just makes things confusing.

Swordfish
  • 12,971
  • 3
  • 21
  • 43
Brennan Vincent
  • 10,736
  • 9
  • 32
  • 54
1

Both are correct. Which one is better depends on your needs.

per1 is of type person (which in torn is a typedef of struct Person), so if you want to pass it, you pass its address (as you did using the& operator).

per2 is an array of persons, so its type is actually an array address and that is why you can pass it as-is. If you have no need for an array of person, use the first option.

Mike
  • 4,041
  • 6
  • 20
  • 37
Daniel
  • 144
  • 1
  • 9
  • *per2 is an array of persons, so its type is actually an array address* - The type of per2 is person[1]. – Swordfish May 21 '19 at 09:36