I have a program which is processing list in c, it is working perfectly as long as I have it in one source file, when I try to separate it and compile it got this error “ delete_functions.c:15:13: error: unknown type name ‘nodetype’ ” same error goes for functionality_functions.c and insert_functions.c here is the code
main.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "types.h"
#include "delete_functions.h"
#include "insert_functions.h"
#include "functionality_functions.h"
int main(){
//i did not upload all the main function code because it is way to long
}
types.h
typedef char AirportCode[4];
typedef struct nodetype{
char Airport[4];
struct nodetype *next;
} nodetype;
delete_functions.h
void Delete(nodetype *list,char node[4]);
void DeleteLast(nodetype *list);
functionality_functions.h
void print(nodetype *head);
nodetype *search(nodetype *list,char item[4]);
nodetype *create();
insert_functions.h
void *InsertLast(nodetype *list,char item[4]);
void *InsertAfter(nodetype *list,char item[4],char node[4]);
According to the GCC error message, there error is in the delete_functions.c file.
Presumably, it looks like this at the beginning:
#include "delete_functions.h"
Since delete_functions.h does not itself include types.h, you need to include it first:
#include "types.h"
#include "delete_functions.h"
Alternatively, you can add include guards to your headers so, that they can safely be included multiple times, like this for types.h:
#ifndef TYPES_H
#define TYPES_H
typedef char AirportCode[4];
typedef struct nodetype{
char Airport[4];
struct nodetype *next;
} nodetype;
#endif
And for delete_functions.h:
#ifndef DELETE_FUNCTIONS_H
#define DELETE_FUNCTIONS_H
void Delete(nodetype *list,char node[4]);
void DeleteLast(nodetype *list);
#endif
The *_H include guard macros are necessary because otherwise, main.c would not compile anymore: each type in types.h can only be defined once per translation unit, and without the guards, every *.h would bring in another definition, leading to compiler errors.
I went through all StackOverflow threads regarding this but could not find one that matched my problem.
I am trying to implement different data structures (implemented in stack.c, queue.c) which get basic functions from another file storage.c. Here are their header files -
storage.h
typedef struct _circular_list
{
int *array, head, tail;
size_t size, count;
} circular_list;
typedef circular_list *clist;
clist Initialize(size_t);
clist WriteAtTail(clist, int);
int RemoveAtHead(clist);
int RemoveAtTail(clist);
clist WriteAtHead(clist, int)
stack.h
#include "storage.h"
#define stack clist
#define push(s, i) WriteAtTail(s, i)
int pop(stack);
int popKey(stack, int);
queue.h
#define queue clist
#define EnQueue(q,i) WriteAtTail(q,i)
#define DeQueue(q) RemoveAtHead(q)
I include them in the main C file
driver.c
#include <stdio.h>
#include "stack.h"
#include "queue.h"
Now if i try to compile them using
gcc -o driver driver.c storage.c stack.c queue.c
I get an error unknown type name 'clist' in queue.h.
If I try to include storage.h in queue.h as well, I get an error that I have multiple declarations for the structure.
How do I go about compiling this?
If you don't include storage.h in stack.h or queue.h you have to include it in your driver.c file before including one of the other files. Otherwise the compiler does not know about the declarations of storage.h.
A better solution is to include storage.h directly in stack.h and queue.h. To avoid getting compiler errors due to multiple declarations you have to change your storage.h like this:
#if !defined(INC_STORAGE_H)
#define INC_STORAGE_H
/* original storage.h contents go here */
#endif /* INC_STORAGE_H */
Or simply write #pragma once at the beginning of the storage.h if your compiler supports it. (If you're writing a library for other people to use I recommend the first solution)
I am learning to write programs in professional way. Like, by creating separate .C and .h file.i decided to write a simple code with structures but I am getting errors.
I have done these things :
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
struct list{
int a;
struct list *next;
};
typedef struct list LIST;
LIST *pHead=NULL,*pCurrent=NULL;
void display(void);
#endif
/*---list.c file ---*/
#include "main.h"
void display()
{
pHead->a=100;
printf("%d",pHead->a);
}
/*----main.h file-----*/
#ifndef MAIN_H
#define MAIN_H
#include<stdio.h>
#include "list.h"
#endif
/*---main.c file---*/
#include "main.h"
void main(void)
{
LIST *New=pHead;
display();
printf("\n\n%d",New->a);
getch();
}
when i compile the code , I am getting following errors
1>main.obj : error LNK2005: _pCurrent already defined in list.obj
1>main.obj : error LNK2005: _pHead already defined in list.obj
can anyone please tell me what I am doing wrong ? Am I including something twice because of which I am getting redeclaration error ?
This is because you define things in your header, as opposed to merely declaring them.
This:
LIST *pHead=NULL,*pCurrent=NULL;
means that every C file that includes the list header, tries to create two global variables. When you then link these C files together, those variables collide. This is broken, you should never do that. Never define things in a header.
You defined the objects in a header file and then included them in multiple source files thus breaking the one definition rule.
If you want to create global variables which you can use across different translation units, you should use the extern keyword.
Generally speaking, .c files contain embodiment of variables, functions, etc.; while .h files contain prototypes of variables, functions, etc., found in it's companion .c file.
It is generally the case that variable and function bodies are not placed in a .h file; only variable and function prototypes should be placed in .h files.
When considering how to split-up code into separate files, it is important to consider which functions, structures and macros are the most primitive. For example, if you write two functions, and function 'a' calls function 'b', function 'b' is most primitive.
The idea is to group functions into a 'c' file that are related, and are at a similar primitive level.
In the case of this question, the more primitive list functions should be embodied in list.c. Then 'list.h' is used to prototype functions and structures used by other less primitive .c files such as main.c.
The most primitive functions are also the most self sufficient. While less primitive functions should call more primitive functions, the reverse makes for clumsy code-flow.
Now to review the question code:
/*---list.c file ---*/
#include "main.h"
list.c should be considered as more primitive than main.c. Hence, having list.c include main.h is (professionally) not a good idea. list.c, being more primitive should be more self-sufficient.
Rather than including main.h, it would be better for list.c to include it's own list.h so that it has access to it's own `struct list' definition, etc.
void display()
{
pHead->a=100;
printf("%d",pHead->a);
}
In order to better isolate list.c, the above function should not reference a 'global' variable (pHead). Rather, it would be better to have the 'node to display' passed into the function as an argument.
With this in mind, here are how 'list.c' and 'list.h' might be improved:
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
typedef struct NODE_S
{
int a;
struct list *next;
} NODE_T;
typedef struct LIST_S
{
NODE_T *head;
} LIST_T;
extern void NodeDisplay(NODE_T *node);
#endif
/*---list.c file ---*/
#include <stdio.h> // printf()
#include "list.h" // NODE_T, LIST_T
void NodeDisplay(NODE_T *node)
{
printf("%d\n",pHead->a);
return;
}
Note that pHead and pCurrent are not prototyped, or embodied, in list.h or list.c Those variables are not used in list.c, and there is no functional reason to place them in list.h
Now examine main.h and main.c as they are in the question code:
/*----main.h file-----*/
#ifndef MAIN_H
#define MAIN_H
#include<stdio.h>
#include "list.h"
#endif
In isolation, what is the purpose that main.h requires stdio.h and list.h? If they were removed, would there be something left 'undefined' in 'main.h'? Perhaps these two include files don't really belong in main.h. "But if they are removed from main.h, why even have a main.h?" Good point. perhaps main.h serves no purpose and perhaps should not even exist.
The main.c file is the least primitive of all files, and shouldn't generally export anything to other (more primitive) files.
/*---main.c file---*/
#include "main.h"
void main(void)
{
LIST *New=pHead;
display();
printf("\n\n%d",New->a);
getch();
}
So what exactly does main.c need? It needs calls printf(), so it will need to include stdio.h. It calls display(), and references the LIST structure, so it needs list.h.
Yes, those .h files were included in main.h; good point. However, the code will be less clumsy (more professional) if main.c includes exactly what it needs explicitly.
With this philosophy in mind, here is a reworked main.c, without a superfluous main.h:
/*---main.c file---*/
#include <stdio.h> // printf()
#include <conio.h> // getch()
#include "list.h" // NodeDisplay(), LIST_T
int main(void)
{
LIST_T pList =
{
.head = NULL
};
/* Allocate & Insert a node into the list. */
NodeCreate(&pList, 100);
NodeDisplay(pList.head);
getch();
return(0);
}
This version of main.c includes exactly what is required, and appropriately calls less primitive functions. It has no need for 'global variables' because it passes its local storage to more primitive functions as needed.
Oh! you noticed the function NodeCreate()!
While the operation of allocating and inserting a new list node could be performed in main.c, such an operation is most likely a common occurrence that fits nicely with other linked list operations. Hence, add such a function to list.c:
/*---list.c file ---*/
#include <stdio.h> // printf()
#include <stdlib.h> // malloc()
#include "list.h" // NODE_T, LIST_T
void NodeDisplay(NODE_T *node)
{
printf("%d\n",node->a);
return;
}
void NodeCreate(LIST_T *list, int a)
{
NODE_T *newNode = malloc(sizeof(*newNode));
if(NULL == newNode)
{
fprintf(stderr, "malloc(newNode) failed.\n");
goto CLEANUP;
}
if(NULL == list)
{
fprintf(stderr, "Passing NULL as the list address not allowed.\n");
goto CLEANUP;
}
/* Initialize new node fields (payload) */
newNode->a = a;
/* Link newNode as new 'list head' node. */
newNode->next = list->head ? list->head->next : NULL;
list->head = newNode;
newNode=NULL;
CLEANUP:
if(newNode)
free(newNode);
return;
}
And so that this function can be called from the less primitive main.c, add a prototype of the function to list.h:
/*---list.h file-------*/
#ifndef LIST_H
#define LIST_H
typedef struct NODE_S
{
int a;
struct list *next;
} NODE_T;
typedef struct LIST_S
{
NODE_T *head;
};
extern void NodeDisplay(NODE_T *node);
extern void NodeCreate(LIST_T *list, int a);
#endif
See spoiler code here.
I have a struct my_struct I found a guide saying there is a linked list that is really easy to use, all I need to do is include a task list_head in my struct, but I don't understand how to traverse this list correctly because I don't know how the list is actually structured
[edit] How does this kernel link list actually work? Please explain.
#include <linux/blkdev.h>
#include <linux/bio.h>
#include <linux/module.h>
#include <linux/slab.h>
#include <linux/init.h>
try this outside of kernel:
#include "list.h"
// my list of elements
struct my_struct
{
struct task list_head;
}
I then declare the head of my list:
struct my_struct *head;
Memory is malloc for the head like this:
head = malloc(sizeof(*head));
I could use something like;
int count_elements_in_list()
{
int size = 0;
struct my_list *pos;
list_for_each(pos, head)
{
size++;
}
return size;
}
Can someone explain how this linked list actually works?
In your code, you included "module.h"; which is a standard include module for most all Linux kernel modules. The "module.h" file includes "list.h".
(These include headers can be found under /usr/src/linux/)
-
The 'list.h' kernel header file defines the -only- acceptable linked list implementation for the Linux kernel (as per kernel.org folks). In tern, 'list.h' includes 'types.h', which define the following:
struct list_head {
struct list_head *next, *prev;
}
In the code supplied to your question:
struct task list_head;
'struct task' contains a 'struct list_head' element. Then later:
list_for_each()
which is defined in 'list.h', which requires uses 'pos' and 'head' to iterate the list.
Here's my problem: I need to implement a FIFO/LIFO list stack as ADT species 1. My program is modular and it have an item.h module:
#ifndef ITEM_H_INCLUDED
#define ITEM_H_INCLUDED
typedef struct
{
char stringa[20];
int numero;
} Item;
#endif // ITEM_H_INCLUDED
The head.h module:
#ifndef HEAD_H_INCLUDED
#define HEAD_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
#include "item.h"
void QUEUEinit();
int QUEUEempty();
void QUEUEput_top(Item);
void QUEUEput_bottom(Item);
Item QUEUEget_top();
Item QUEUEget_bottom();
#endif // HEAD_H_INCLUDED
The main.c and data.c; what i need is how i declare a QEUEnode struct and where.
Thank you for the help :)
Since none of your QUEUE* functions receive a QUEUEnode *, you can hide it in the head.c file, along with the QUEUEnode root; that they operate on.
If you want to use multiple queues, then it should probably be in the head.h file so they can be created in main.c. For this, you'll also need to modify the functions to accept a queue to operate on.