7

I have this in a C file:

struct T
{
    int foo;
};

the C file has an include to an h file with those lines:

typedef struct T T;
void listInsertFirst(T data, int key, LinkedList* ListToInsertTo);

the function listInsertFirst is the one I'm getting the warning on. How can I fix it?

Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
Belgi
  • 14,542
  • 22
  • 58
  • 68
  • thanks,and what if I want the type to be knonwn if someone includes the h file ? – Belgi May 13 '11 at 19:32
  • 2
    One thing you should be aware of is that you're passing a `struct` *by value* here. That's almost surely a bad idea... – R.. GitHub STOP HELPING ICE May 13 '11 at 19:36
  • Any reason why you are typedef-ing in the C file rather than in the header file. Also, you can typedef the struct straight out by having something like struct T { int foo;} T; – Gangadhar May 13 '11 at 19:37
  • What parameter is the compiler referring to? – Jeff Mercado May 13 '11 at 19:41
  • I'm actually not sure what is the right thing to do when implementing (any dictionary like) DS:should the person that called the insert function do the memory allocation and pass a pointer,or should he pass the object and the insert function should do the allocation ? – Belgi May 13 '11 at 19:41
  • @Jeff Mercado I'm not sure (it doesn't say) but I think that it's the T type parameter – Belgi May 13 '11 at 19:43
  • @user: Well, if `struct T` is actually defined somewhere, then this should not be a problem. Is the defintion of `struct T` in the file before you defined type `typedef struct T T;` or is it actually in a different file? Or is it in a header that you didn't actually include? – Jeff Mercado May 13 '11 at 19:46
  • @Jeff Mercado I moved the decleration to the header and it's ok now :) but I'm still not sure about what I wrote in my previous comment to Gangadhar.thoughts ? – Belgi May 13 '11 at 19:49
  • @user: To be honest, I can't say for sure. There isn't enough information here to make a good suggestion. I don't know how you've implemented things. Though as that is a different problem now, you should ask about that in a new question (with much more information about your types). – Jeff Mercado May 13 '11 at 19:53
  • @Gangadhar: "typedef struct { int foo; } T;" with your first T ("struct T {...") only needed if the struct needs to refer to itself, such as "typedef struct Node { struct Node *next; } Node;". – Fred Nurk May 13 '11 at 20:43

5 Answers5

2

When you include the header file, the compiler knows that T is a structure of unknown size and that listInsertFirst wants one as its first argument. But the compiler cannot arrange a call to listInsertFirst as it doesn't know how many bytes to push on the stack for the T data parameter, the size of T is only known inside the file where listInsertFirst is defined.

The best solution would be to change listInsertFirst to take a T* as its first argument so your header file would say this:

extern void listInsertFirst(T *data, int key, LinkedList* ListToInsertTo);

Then you get an opaque pointer for your T data type and, since all pointers are the same size (in the modern world at least), the compiler will know how to build the stack when calling listInsertFirst.

mu is too short
  • 426,620
  • 70
  • 833
  • 800
2

As we've found out in the comments, the problem was that the definition of struct T occurred after the definition of T in the header. You really have things backwards here. The header should be defining all the types and function prototypes and your C files should be using them.

What you want to be doing instead is change the signature of your insert function to receive a pointer to your data and the size of the data. Then you can allocate some memory for the data, copy it and store it. You don't need a specific type, just declare it a void *.

void listInsertFirst(void *data, size_t data_size, int key, LinkedList* ListToInsertTo);

Then the caller would do something like this:

struct T { int foo; };
struct T x = { ... };
int someKey = ...;
LinkedList *someList = ...;
listInsertFirst(&x, sizeof x, someKey, someList);
Jeff Mercado
  • 129,526
  • 32
  • 251
  • 272
0
  1. Define struct T in header, not in .c file;
  2. Choose different names for structure and typedef.
i486
  • 6,491
  • 4
  • 24
  • 41
0

Are you sure it is the first parameter that is the problem? To be sure, try changing the parameter type from T to int temporarily. More than likely, the third parameter is actually the problem.

Many compilers don't point at the problem in these sorts of issues very well.

wallyk
  • 56,922
  • 16
  • 83
  • 148
0

Try to move the structure definition to the h file, before the typedef.

Amir
  • 32
  • 3
  • the problem with this is that I have : typedef struct LinkedList { ListNode* head; ListNode* tail; }LinkedList; which uses the type "ListNode", If I put this typedef struct on the h file I'd have to add the typedef struct of "ListNode",but no one should be aware of this type... – Belgi May 13 '11 at 19:38
  • But LinkedList must be aware of ListNode. So, if someone is aware of LinkedList, it must be aware also with ListNOde. You can also add another h file: Add ListNode to the new h file and include it in your original h file – Amir May 13 '11 at 19:42