Thread: struct / header files black magic?!?

  1. #1
    Registered User
    Join Date
    Oct 2021
    Posts
    8

    Question struct / header files black magic?!?

    Hello there

    I'm progressing through a project with chained lists.

    I made a bunch of utility functions to handle this type of structure as described in the project instructions :

    Code:
    typedef struct s_list
    {
        struct s_list    *next;
        void            *data;
    } t_list;
    I went to test my code, and made a header that included this structure :

    Code:
    typedef struct s_list
    {
        void            *data;
        struct s_list    *next;
    } t_list;
    This made my code misbehave in a way I really really don't understand. Example of a function to create an element :

    Code:
    #include "ft_list.h"
    
    t_list    *ft_create_elem(void *data)
    {
        t_list    *new;
    
        new = malloc(sizeof(*new));
        if (new == NULL)
            return (NULL);
        new->next = NULL;
        new->data = data;
        return (new);
    }
    Example of a function to add an element to the front of a list :

    Code:
    #include "ft_list.h"
    
    void    ft_list_push_front(t_list **begin_list, void *data)
    {
        t_list    *new;
    
        if (! begin_list)
            return ;
        new = ft_create_elem(data);
        if (new == NULL)
            return ;
        new->next = *begin_list;
        *begin_list = new;
    }

    As you can see, absolutely unremarkable, unoriginal functions which use ->next and ->data as you'd expect them to.

    However, when coupled with my header file, this kind of wizardry happened :

    Code:
    new element address: 0x7fffea3ba2a0
    new->data is: 0x7ffff2595952
    list address: 0x7fffea3ba2a0
    list->data: (nil)
    list->next: 0x7ffff2595952
    Only after I rectified my header to have next first and data second did the code work as intended :

    Code:
    new element address: 0x7fffebec12a0
    new->data is: 0x7ffff44bc8a2
    list address: 0x7fffebec12a0
    list->data: 0x7ffff44bc8a2
    list->next: (nil)
    I compiled 3 c files together like this :

    Code:
    ./main.c
    ./ex00/ft_create_elem.c
    ./ex01/ft_list_push_front.c
    By using

    Code:
    gcc (my 3 files) -I .
    To indicate to gcc that the header it was to use was located where I was... but I had several header files like this :

    Code:
    ./ft_list.h
    ./ex00/ft_list.h
    ./ex01/ft_list.h
    I would assume the problem was that several header files were being included... BUT I protected them adequately with

    Code:
    #ifndef FT_LIST_H
    # define FT_LIST_H
    [...]
    #endif
    What the hell happened here? I don't understand.

  2. #2
    Registered User
    Join Date
    Dec 2017
    Posts
    1,194
    You have made the rather common mistake of showing us stuff that has nothing to do with the problem. In essence, you have shown us your assumptions, but obviously your assumptions are wrong or else you would see where the trouble is yourself.

    What you need to do is take a definite set of files, compile and run them, make sure they show the problem, then, if you still can't find the solution yourself, post all of those exact files.
    We live as it were by chance, and by chance we are governed. - Seneca

  3. #3
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    38,811
    Code:
    typedef struct s_list
    {
        struct s_list    *next;
        void            *data;
    } t_list;
    > wibble wibble wibble
    Code:
    typedef struct s_list
    {
        void            *data;
        struct s_list    *next;
    } t_list;
    Well 'duh', you managed to declare the same thing twice with the same name, but got the members swapped over in the process.

    Define it ONCE and be done.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  4. #4
    Registered User
    Join Date
    Dec 2017
    Posts
    1,194
    I thought he meant that he replaced the first struct definition with the second, not that he defined it one way in one compilation unit and the other way in another compilation unit. That's ridiculous. Posting the entire program would have made that clear.

    one.c (compilation unit 1)
    Code:
    struct X {
        int a;
        int b;
    };
     
    void f(struct X *x);
     
    int main() {
        struct X x;
        x.a = 1;
        x.b = 2;
        f(&x);
        return 0;
    }
    two.c (compilation unit 2)
    Code:
    #include <stdio.h>
     
    struct X {
        int b;
        int a;
    };
     
    void f(struct X *x) {
        printf("%d %d\n", x->a, x->b);
    }
    This prints the values in the order 2 1.
    We live as it were by chance, and by chance we are governed. - Seneca

  5. #5
    Registered User
    Join Date
    Nov 2021
    Posts
    3
    What you need to do is take a definite set of files, compile and run them, make sure they show the problem, then, if you still can't find the solution yourself, post all of those exact files.

    Last edited by Salem; 1 Week Ago at 07:31 AM. Reason: Removed spam link

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. typdef, struct, and header files
    By maxzoran in forum C Programming
    Replies: 11
    Last Post: 08-11-2010, 06:41 PM

Tags for this Thread