0

I am trying to understand C syntax and I have done the following example. I have placed a function pointer *func as a property of my Person struct, which returns a struct Person.

typedef struct
{
    int age, salary;
    struct Person(*func) (int age, int salary);
} Person;

Person other_func(int age, int salary)
{
    Person* person = malloc(sizeof(Person));
    person->age = age;
    person->salary = salary;
    return *person;
};

int main()
{
    Person p;
    p.func= other_func;
    p = p.func(30, 3000);
}

This gives me "Can not convert Person to Person" on the last line. I suppose this is because the one is Person and the second is struct Person, but inside the Person struct, I have have my function as struct Person(*func_1) (int age, int salary); because it raises a compilation time error if I use Person instead of struct Person. So I used struct Person instead. Is this the problem ? How would I achieve what I am trying to do ?

dimitris93
  • 4,155
  • 11
  • 50
  • 86

2 Answers2

4
typedef struct
{
    int age, salary;
    struct Person(*func) (int age, int salary);
} Person;

Shouldn't this be:

typedef struct Person
{
    int age, salary;
    struct Person(*func) (int age, int salary);
} Person;

In the first case, you don't name your struct, so struct Person isn't a valid type name. My version of GCC gives more helpful output:

$ gcc test.c
test.c: In function ‘main’:
test.c:20:11: warning: assignment from incompatible pointer type
     p.func= other_func;
           ^
test.c:21:5: error: invalid use of undefined type ‘struct Person’
     p = p.func(30, 3000);

Note that the two names don't need to match. All you're doing is combining a typedef and a struct declaration. This is would be equally valid:

struct X {
    int age, salary;
    struct X(*func) (int age, int salary);
};

typedef struct X Person;

You may want to read this excellent answer about struct typedef'ing.

Community
  • 1
  • 1
Brendan Long
  • 53,280
  • 21
  • 146
  • 188
  • you are right. what exactly is the difference between the two ? I thought it was exactly the same ? – dimitris93 Apr 07 '15 at 18:35
  • 1
    For anyone else wondering why defining a type like this isn't an error, [it's because this is how you do forward declaration in C](http://stackoverflow.com/questions/18658438/what-is-forward-declaration-and-the-difference-between-typedef-struct-x-and). – Brendan Long Apr 07 '15 at 18:49
2

typedef struct X {} Y;

X - is a TAG which you can convert to something useful with syntax 'struct X val'. Y is typename which you can use directly: 'Y val;'

Then, type name Y (in your case 'Person' is not visible inside of struct as it is defined later. That is why you have to use TAG inside of struct:

typedef struct tag_Person {
    struct tag_Person (*func)(int arge, int salary);
} Person;
fukanchik
  • 2,811
  • 24
  • 29
  • I don't think the tag/ type name distinction is correct (they are both type names), but you're right that the second one isn't available yet. – Brendan Long Apr 07 '15 at 18:38