Thread: Structs in C

  1. #1
    Registered User
    Join Date
    Dec 2014
    Posts
    1

    Structs in C

    Ok, I've checked out a few posts on how to use structs in c, but it still confuses me a great deal. I have no problem understanding them in C++, but I guess I don't yet understand what the limitations are when switching to C.

    I have some code here where I try to declare a struct then pass it as a parameter into a function to do something to it:

    Code:
    struct _user {
      char * initial[3];
      int pos;
    } user;
    
    
    int initial_add (struct user * initial_list, int initials, char * buffer) {
      int i = 0;
      for (i = 0; i < initials; i += 1) {
        if (strcmp(initial_list[i].initial,"..") != 0)
          break;
      }
      strcpy(initial_list[i]->initial,buffer);
      return i;
    }
    I get the error :
    server2.c:15: warning: "struct user" declared inside parameter list
    server2.c:15: warning: its scope is only this definition or declaration, which is probably not what you want

    server2.c: In function `initial_add':
    server2.c:18: error: invalid use of undefined type `struct user'
    server2.c:18: error: dereferencing pointer to incomplete type
    server2.c:21: error: invalid use of undefined type `struct user'
    server2.c:21: error: dereferencing pointer to incomplete type

    Could someone please explain this to me? It would be greatly appreciated.

  2. #2
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    This is the name of the structure you declare
    Code:
    struct _user
    This is the name of the type you use in the function call
    Code:
    struct user
    Notice they are not the same -- one has an _underscore, one doesn't. They must match.

    Also, your function takes a pointer to struct. You must make sure you pass in a pointer to a struct of the right kind.

    Lastly, if you thought the 'user' bit at the end of the struct would fix that for you, it wont. What you did there is create a type called struct _user and declare a variable names user of that type. If you wish to create new type names for a struct, you need to use the typedef keyword. Google for examples.

  3. #3
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    It's looks like you've got it mixed up with the typedef form:

    Code:
    typedef struct _data
    {
      //...
    } data;
    The problem is that user is a definition of type _user, not the declaration of the type :

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    struct _data
    {
        int a;
    } /* anything put here is a definition, and is assignable to */;
    
    int getData( struct _data dat );
    
    int main()
    {
        struct _data dat;
        dat.a = 10;
    
        printf("%d\n", getData( dat ));
    
        return 0;
    }
    
    int getData( struct _data dat )
    {
        return dat.a;
    }
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  4. #4
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Alpo
    The problem is that user is a definition of type _user, not the declaration of the type :
    More accurately, user is the name of an object of the type struct _user, an object that you defined even as you declared struct _user.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  5. #5
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by laserlight View Post
    More accurately, user is the name of an object of the type struct _user, an object that you defined even as you declared struct _user.

    Right (I sometimes get mixed up with a "type declaration" versus "object 'of type' definition" with C structs). C style structs are a pretty confusing thing for someone just beginning I think. Especially with all the typedefs that most examples use ( and C++ handles it like that anyways which would increase the confusion ).

    I think the confusion comes from the fact that the typedef version is usually indented like a regular struct declaration:

    Code:
    typedef struct Data
    {
        int a;
    } Name;
    
    // Makes more sense if you look at it like this:
    
    typedef   struct Data{ int a; }   Name ;
    In truth it might make more sense to uncouple the typedef from the declaration:

    Code:
    // Declaration of a user defined type called data:
    struct Data
    {
        int a;
    };
    
    // a typedef which says the typename 'Name' is equivalent to declaration of object of type 'struct Data':
    typedef struct Data Name;
    For the OP, I updated the last example I posted to show how the typedef version can be used the same as the longer version:

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    // Declaration of type
    
    struct _data
    {
        int a;
    } /* anything put here is a definition of an object of type _data, and is assignable to */;
    
    // DATA becomes a more convenient typename 
    typedef struct _data DATA;
    
    int getData( struct _data dat );
    
    int main()
    {
        /* The next two lines are equivalent, but the typedef allows us to 
           declare 'dat' using the alias, which makes it seem more like a built in type. */
        DATA dat;
        struct _data dat2;
    
        dat.a = 10;
        dat2.a = 20;
    
        printf("%d\n", getData( dat ));
        printf("%d\n", getData( dat2 ));
    
        return 0;
    }
    
    int getData( struct _data dat )
    {
        return dat.a;
    }
    Last edited by Alpo; 12-08-2014 at 11:38 PM.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

  6. #6
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    I do not suggest DATA as a type name though. While it is true that we have FILE from the standard library for historical reasons, these days names that are entirely uppercase are conventionally used for macros and constants.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  7. #7
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by laserlight View Post
    I do not suggest DATA as a type name though. While it is true that we have FILE from the standard library for historical reasons, these days names that are entirely uppercase are conventionally used for macros and constants.
    Whoops lol, I started doing that because I was doing so much Win32 for the past several months and wanted my stuff to fit in (also that's where I started doing Hungarian notation, from the other thread). I'll need to straighten my act up.
    WndProc = (2[b] || !(2[b])) ? SufferNobly : TakeArms;

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 01-08-2013, 07:55 AM
  2. Typedef Structs inside Typdef structs
    By gremory in forum C Programming
    Replies: 21
    Last Post: 12-30-2011, 07:48 PM
  3. [ noob question ] Help with structs within structs
    By Riverfoot in forum C Programming
    Replies: 3
    Last Post: 04-26-2011, 07:24 PM
  4. Passing Structs Into An Array Of Structs.
    By TheTaoOfBill in forum C Programming
    Replies: 3
    Last Post: 10-07-2010, 09:38 AM
  5. passing structs & pointers to structs as arguments
    By Markallen85 in forum C Programming
    Replies: 6
    Last Post: 03-16-2004, 07:14 PM

Tags for this Thread