0

Description

I'm trying to understand pointers, linked lists, structures and such in C. As a learning experience, I have written this small program, which:

  • defines some basic structures and creates links between them, using structure pointers.
  • iterates over the whole linked lists and prints out all variables.
  • creates another structure, but doesn't insert it into the linked list.
  • calls a function insertEntry which inserts a given struct between one element of the linked list and his direct follower.

What I've done so far:

  • This Stack Overflow answer says: "That actually means that there is another function/declaration [..] elsewhere in your source code structure that has a different function signature."

    • I've checked for typos in the function definition, declaration and its call.
    • I've checked the amount and type of the parameters. Both parameters of insertEntry are always two structs of the same type.
  • This different Stack Overflow answer says: "You have forgotten to #include "client.h", so the definition", but I've also checked that. Both the actual filename on the filesystem and the #include.

===> I don't get, where my error is.


ex1_insertStructure_linkedList.h:

void insertEntry(struct entry, struct entry);

ex1_insertStructure_linkedList.c:

#include <stdio.h>
#include "ex1_insertStructure_linkedList.h"

struct entry {
    int value;
    struct entry *next;
};

// clangtidy: conflicting types for 'insertEntry' [clang-diagnostic-error]
void insertEntry(struct entry given_entry, struct entry entry_to_insert) {

    printf("Print inside insertEntry method: %i\n", given_entry.value);
    struct entry *second_pointer = (given_entry).next;

    // entry_to_insert is now the element in the middle
    given_entry.next = &entry_to_insert;

    // the third element
    entry_to_insert.next = second_pointer;

    return;
}

int main(int argc, char *argv[]) {
    struct entry n1, n2, n3;

    n1.value = 1;
    n1.next = &n2;

    n2.value = 32;
    n2.next = &n3;

    n3.value = 34242;
    n3.next = (struct entry *)0;

    struct entry *list_pointer = &n1;

    while (list_pointer != (struct entry *)0) {
        int printValue = (*list_pointer).value;
        list_pointer = (*list_pointer).next;
        printf("%i\n", printValue);
    }

    printf("--------------------\n");
    list_pointer = &n1;

    struct entry a;
    a.value = 999999;
    a.next = (struct entry *)0;

    // clangtidy: argument type 'struct entry' is incomplete [clang-diagnostic-error]
    insertEntry(n1, a);

    while (list_pointer != (struct entry *)0) {
        int printValue = list_pointer->value;
        list_pointer = list_pointer->next;
        printf("%i\n", printValue);
    }

    return 0;
}
7
  • 1
    You can start by describing what the actual error is and where it is. Commented Mar 4, 2017 at 22:54
  • @2501 i don't understand your response, the actual error message is included in the source code - where my linter/checking program complained. Commented Mar 4, 2017 at 22:55
  • 3
    You need to "forward-declare" the struct entry in your file ex1_insertStructure_linkedList.h, i.e. before the function declaration: void insertEntry(struct entry, struct entry);, that is put the following struct entry; before that function declaration. Commented Mar 4, 2017 at 22:56
  • @nibro ooh, that fixes my error, thanks! if you turn your comment into an answer, i'll upvote and mark it as accepted answer. Commented Mar 4, 2017 at 22:58
  • When I compile the header with GCC 6.3.0 (on macOS Sierra 10.12.3) and no warning options whatsoever, I get a message like: In file included from chkhdr-2684.c:1:0:xyz.h:1:25: warning: ‘struct entry’ declared inside parameter list will not be visible outside of this definition or declarationvoid insertEntry(struct entry, struct entry);. If your compiler didn't generate such warnings, you need to get a better compiler, or turn on more warnings. If you saw such warnings but didn't mention them in the question, then you most certainly should have done. Commented Mar 4, 2017 at 23:18

2 Answers 2

3

You should place struct entry declaration in ex1_insertStructure_linkedList.h :

struct entry {
    int value;
    struct entry *next;
};

void insertEntry(struct entry, struct entry);
Sign up to request clarification or add additional context in comments.

6 Comments

You don't necessarily need to define struct entry in ex1_insertStructure_linkedList.h, but just forward-declare it, which is better if you also strive for "information hiding".
@nbro True, but I don't think "information hiding" is something OP is looking for :)
@nbro Yes you do need to in this case, otherwise the function cannot be shared.
@2501 What do you mean by "the function cannot be shared"? You mean that insertEntry cannot be shared?
@nbro Other translation units won't see the definition of the struct and the code won't compile. The solution given by SegFault is correct in this case, yours only delays the problem.
|
2

You need to "forward-declare" the struct entry in your file ex1_insertStructure_linkedList.h, i.e. before the function declaration: void insertEntry(struct entry, struct entry);, that is put the following struct entry; before that function declaration.

The reason for this is because when the compiler encounters insertEntry(struct entry, struct entry);, it doesn't know anything about struct entry. By forward declaring struct entry, you "ensure" to the compiler that the struct entry is defined somewhere in a source file.

2 Comments

When a compiler encounters struct entry as parameter within function declaration, it already assumes, that entry is a tag name of struct of incomplete type. That is why it's legal to declare a pointer like struct xyz *p = NULL without any prior declaration of struct xyz. The forward declaration may be considered a good practice, but it is not required. In both case, the type is incomplete, so one cannot pass arguments to such function nor access objects of such type within the current translation unit.
@GrzegorzSzpetkowski I know that the type is incomplete and you could not access the definition of it if it was defined in another source file.

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.