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 ?

7
  • 1
    Try changing the very first line to typedef struct Person. Commented Apr 7, 2015 at 18:34
  • 2
    also this implementation has memory leak. Commented Apr 7, 2015 at 18:35
  • @BLUEPIXY can you explain where exactly is the memory leak ? because i do not see it Commented Apr 7, 2015 at 18:36
  • 2
    memory leak: 1 malloc(), 0 free() ... BTW, you need to #include <stdlib.h> Commented Apr 7, 2015 at 18:37
  • 4
    Person* person = malloc(sizeof(Person)); person->age = age; change to Person person = {age, salary}; return person; no need malloc. because you return Person(copy) Without release parson. Commented Apr 7, 2015 at 18:39

2 Answers 2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

you are right. what exactly is the difference between the two ? I thought it was exactly the same ?
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.
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;

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.