why the redfinition in c - c-preprocessor

//-----a.h-------
#ifndef ELEMTYPE
#define ELEMTYPE
typedef int ElemType;
#endif
//------test.c-----
#include <stdio.h>
#define ELEMTYPE
typedef double ElemType;
#include "a.h";
int main(){
printf("%lu\n", sizeof(ElemType));
}
// my question is that i've already defined ELEMTYPE in test.c, as far as i concerned, the typedef in a.h should not be inlcuded in test.c. why i encountered the problem of redefinition of ElemType?

Related

using struct elements in function that is in another source file

New to learning c and I am having difficulties with writing a function in another source file that uses struct variables from the first source file.
basically I need to create a bubblesort function in another file to be used in my driver
this is what i am trying to do
driver.c
#include<stdio.h>
#include<stdlib.h>
#include<sort.c>
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
int main(){
sort();
}
sort.h
void sortList(IORB * head, int(*prio)(int));
sort.c
void sortList(IORB * head, int(*prio)(int)){
// do stuff
}
but i get this error:
unknown type IORB in the sort function.
how can pass the IORB to the function ?
Updated code after trying the answer:
driver.c
#include<stdio.h>
#include<stdlib.h>
#include "sort.h"
#include "iorb.h"
//removed the typedef in the driver
iorb.h
#ifndef IORB_H
#define IORB_H
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
#endif
sort.h
#ifndef SORT_H_
#define SORT_H_
void sortList(IORB * head, int(*prio)(int));
#endif
sort.c
#include "sort.h"
#include<stdlib.h>
#include<stdio.h>
#include "iorb.h"
void sortList(IORB * head, int(*prio)(int)){
//do stuff
}
You want to put your type declaration / typedef in a header file:
#ifndef IORB_H
#define IORB_H
typedef struct iorb {
int base_pri;
struct iorb *link;
char filler[100];
} IORB;
#endif
Then include that header file in sort.h:
#include "iorb.h"
and you want to include the sort.h in your sort.c:
#include "sort.h"

How to forward declare a typedef structure in C which has no tag

file1.h: Library code. CANT change it
#ifndef FILE1_H_
#define FILE1_H_
typedef struct
{
int x;
} MY_STRUCT;
#endif /* FILE1_H_ */
file2.h: user defined. can be changed. How to forward declare above typedef struct which has no tag ?
#ifndef FILE2_H_
#define FILE2_H_
struct MY_STRUCT;
void print(struct MY_STRUCT * obj);
#endif /* FILE2_H_ *
file2.c: user defined. can be changed
#include "file2.h"
#include "file1.h"
#include <stdio.h>
void print(struct MY_STRUCT * obj)
{
printf("x: %d", obj->x);
}
main.c
#include "file2.h"
#include "file1.h"
int main(void){
MY_STRUCT obj1;
obj1.x = 100;
print(&obj1);
}
The code can be seen here. https://paiza.io/projects/wa2PCvUswWyyAzdxxjggxQ?language=c
It's not possible to "forward-declare" a typedef . You will have to give the struct a tag, e.g.:
typedef struct my_struct MY_STRUCT;
// ... later
struct my_struct
{
int x;
};

Error: Unknown type name

I'm new to modular programming and I hope you can help me out :)
So here are my .c .h:
item.h
#define L 31
#define L1 11
typedef struct{
int priority;
char service_type[L];
char client_code[L1];
}*Item;
Item New_client();
item.c
#include <stdio.h>
#include <stdlib.h>
#include "item.h"
Item New_client(){
Item new_c=malloc(sizeof new_c);
printf("Inserire priorita': "); scanf("%d",&new_c->priority);
printf("Inserire servizio: "); scanf("%s",new_c->service_type);
printf("Inserire codice cliente: "); scanf("%s",new_c->client_code);
return new_c;
}
PQ.h
typedef struct Nodo *link;
struct Nodo{
Item item;
link next;
};
void init(link coda);
int empty_(link coda);
link insert_(link h,Item client);
PQ.c
#include <stdio.h>
#include <stdlib.h>
#include "PQ.h"
So as I include PQ.h in PQ.c I get the error: unknown type name 'Item' from CodeBlocks... I can't figure why and what can I do to solve the problem.
You should include item.h in your PQ.h:
#include "item.h"
typedef struct Nodo *link;
struct Nodo{
Item item;
link next;
};
void init(link coda);
int empty_(link coda);
link insert_(link h,Item client);
Update: about error: conflicting types for 'Item'
This becouse preprocessor include item.h twice. You should wrap header with #ifndef __HEADER_NAME__, #define __HEADER_NAME__, #endif combination. See how it can be done for item.h:
#ifndef __ITEM_H__
#define __ITEM_H__
#define L 31
#define L1 11
typedef struct{
int priority;
char service_type[L];
char client_code[L1];
}*Item;
Item New_client();
#endif //__ITEM_H__

Error: unknown type in C. What can be the reason when all required header files are included?

So I cannot figure out the following problem:
I am getting unknown type for orderPtr which is typedef of struct Order even though I have included the header file that declares this type.
Here is the code in queue.h:
#ifndef QUEUE_H
#define QUEUE_H
#include <stdio.h>
#include "book.h"
#include "queue_node.h"
/*
* Queue structure for consumers threads
*/
typedef struct queue {
pthread_mutex_t mutex;
pthread_cond_t notempty;
struct queue_node *rear;
} queuePtr;
void queue_enqueue(queuePtr *, orderPtr *);
orderPtr *queue_dequeue(queuePtr *queue);
#endif
and here this type is declared in book.h:
#ifndef BOOK_H
#define BOOK_H
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <pthread.h>
#include "uthash.h"
#include "customer.h"
#include <errno.h>
#include <unistd.h>
#include "queue.h"
typedef struct order {
char *title;
double price;
char *idnum;
char *category;
} orderPtr;
void order_destroy(orderPtr *);
orderPtr * order_create(char *, double, char *, char *);
#endif
If you follow the include chain, it's like this:
main.c includes book.h
book.h includes queue.h at the top (before the typedef of orderPtr)
queue.h tries to use orderPtr which has not yet been typedef'd = error
Finally comes the typedef of orderPtr.
You can get around this in several ways. One way is that in queue.h you can do:
/*
* Queue structure for consumers threads
*/
typedef struct queue {
pthread_mutex_t mutex;
pthread_cond_t notempty;
struct queue_node *rear;
} queuePtr;
struct orderPtr; // Forward declaration
// The use of struct orderPtr * is allowed because it is a pointer.
// If it wasn't a pointer, it would be an error because the size
// would be unknown.
void queue_enqueue(queuePtr *, struct orderPtr *);
struct orderPtr *queue_dequeue(queuePtr *queue);

Interdependent headers not compiling

I have 2 headers that depend on each other, both are guarded. But compilation fails as if the type weren't declared:
error: unknown type name Type_1
the first header:
#ifndef HEADER1_H
#define HEADER1_H
#include "header2.h"
typedef struct {
int a;
char *b;
} Type_1;
void function(Type_3 *type_3);
#endif
second header
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
How to solve it without resorting to hacks?
You must forward declare at least one struct. I'd personally put them all in one header, since there's not that much there.
First header:
#ifndef HEADER1_H
#define HEADER1_H
#include "header2.h"
typedef struct Type_1 {
int a;
char *b;
} Type_1;
void function(Type_3 *type_3);
#endif
The second header:
#ifndef HEADER2_H
#define HEADER2_H
struct Type_1;
typedef struct {
int a;
char *b;
struct Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
Move all your types definitions to one files and functions declarations to another one.
header1.h
#ifndef HEADER1_H
#define HEADER1_H
typedef struct {
int a;
char *b;
} Type_1;
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
header2.h
#ifndef HEADER2_H
#define HEADER2_H
#include "header1.h"
void function(Type_3 *type_3);
#endif
As you use your structures as imcomplete data types, forward declaration is enough:
#ifndef HEADER2_H
#define HEADER2_H
struct Type1;
typedef struct Type1 Type1;
typedef struct {
int a;
char *b;
Type_1 *c;
} Type_2;
typedef struct {
int a;
char *b;
Type_2 *c;
} Type_3;
#endif
Apply same technique to second file. Though, in source code, you need to include header if you don't use your structures as incomplete types. More information about incomplete data types is available in this MSDN article

Resources