This question already has answers here:
Why are typedef identifiers allowed to be declared multiple times?
(3 answers)
Closed 5 years ago.
Why don't I get the error messages?
I have three header files named DataType.h, printInt.h, printStr.h, and one myApp.c.
DataType.h
typedef int Integer;
typedef char String;
printInt.h
#include "DataType.h"
void printInt(Integer);
printInt.c
#include "printInt.h"
#include <stdio.h>
void printInt(Integer number){
printf("%d\n", number);
}
printStr.h
#include "DataType.h"
void printStr(String*);
printStr.c
#include "printStr.h"
#include <stdio.h>
void printStr(String *str){
printf("%s\n", str);
}
myApp.c
#include "printStr.h"
#include "printInt.h"
Integer main(void){
printInt(20);
printStr("hello");
return 0;
}
Clearly, I have included the DataType.h twice, and I did not use #ifndef to avoid redefinition of Integer and String. Please, someone, tell me how I can get the error messages to demonstrate the directive is working properly.
#ifndef __DATATYPE_H
#define __DATATYPE_H
typedef int Integer;
typedef char String;
#endif
Regardless having #ifndef or not, the gcc complier (version 5.4.0) does not generate any error messages. What's wrong?
Definitions of typedef and prototypes of functions can occur as many times as you want. For example:
typedef int lala;
typedef int lala;
void somePrototype();
void somePrototype();
int main() {
return 0;
}
will compile just fine: https://ideone.com/4EjfaR
Try adding the definition of a function to a header file. You will see then that you get a redefinition error and will require a header guard.
Related
This question already has answers here:
What exactly do C include guards do?
(3 answers)
Closed 4 years ago.
Honestly I'm not used to working in c and maybe I'm wrong as I approach the problem.
I have 3 files and I need to pass data from one to another
//main.c
#include <stdio.h>
#include "process.h"
#include "readFile.h"
int main() {
int numIn=2, numOut=1;
struct data *allData=readData(numIn, numOut);
process(allData, numIn, numOut);
return 0;
}
// readFile.h
#include <stdio.h>
#include <stdlib.h>
struct data {
double *in;
double *out;
};
struct data * readData(int numIn, int numOut) {
//here I initialize and fill an "allData" array of struct data
return allData;
}
//process.h
#include <stdio.h>
#include <stdlib.h>
#include "readFile.h"
int process(struct data * allData, int numIn, int numOut) {
return 0;
}
If I delete "process.h" and try to print "allData" in the main, the correct data are printed without errors, but when I try to process the data in "process.h" I get this compilation error:
In file included from C:\...\main.c:4:0:
C:\...\readFile.h:11:8: error: redefinition of 'struct data'
struct data
^
In file included from C:\...\process.h:11:0,
from C:\...\main.c:2:
C:\...\readFile.h:11:8: note: originally defined here
struct data
^
In file included from C:\...\main.c:4:0:
C:\...\readFile.h:24:15: error: conflicting types for 'readData'
struct data * readData(int numIn, int numOut)
^
In file included from C:\...\process.h:11:0,
from C:\...\main.c:2:
C:\...\readFile.h:24:15: note: previous definition of 'readData' was here
struct data * readData(int numIn, int numOut)
^
Do not place any code in the .h files
.h files are for the data declarations, extern variables declarations and function declarations.
.c files are correct place to have variable and functions definitions.
Move all the code form the .h files to .c files
Also add the .h file guards. It is just the definition. If this definition is already defined - it means that this file was already included and its content should be skipped
#ifdef MYGUARD_H
#define MYGUARD_H
/* .h file content
#endif
This question already has answers here:
Variable declaration in a header file [duplicate]
(5 answers)
Closed 4 years ago.
I am learning at moment C and I really do not understand how header
files works and to be sure I have two Questions.
1) Let's take a look at the following program: main.c:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
functions.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
void printNumber( void )
{
printf("Number = %d\n", number );
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
int number;
extern void printNumber( void );
#endif // FUNCTIONS
The way the program is in the Header file there is no extern keyword
involved so there seems to be reference to number and the program
Outputs:
Num = 0
Number = 0
The first Question is, does number get initialized (is number global
variable or similar if number is present only in the header file)
and is this a legal code/program?
Second scenario, let's take a look at the following code main.c:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
functions.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "functions.h"
void printNumber( void )
{
printf("Number = %d\n", number );
}
functions.h:
#ifndef FUNCTIONS
#define FUNCTIONS
extern int number;
extern void printNumber( void );
#endif // FUNCTIONS
Here the program will not compile due the
`undefined reference to number`
Which force me to declare number in main:
#include <stdio.h>
#include <string.h>
#include "functions.h"
int number;
int main( void )
{
printf( "Num = %d\n", number );
printNumber();
return 0;
}
Which is the Right way and why?
Last thing, why does exactly not apply
to void printNumber( void ) as well. I see that it is working with
or without the extern keyword.
For the first version, in your header file, you define the variable number. That means every translation unit that includes the header file will have a definition of the variable. That's not allowed, you can only have a single definition spread over all translation units.
The solution to that problem is to declare the variable in the header file instead:
extern int number;
The use of the keyword extern marks this as a declaration instead of a definition, the compiler will know that the variable is defined somewhere else.
Then you of course need to define it somewhere. In one single source file put the definition:
int number;
I.e. exactly what you do in your last variant.
In addition to Some programmer dude's answer, I use the following construct:
// functions.h
#indef EXTERN
# define EXTERN extern
#endif
EXTERN int number;
// functions.c
#include "functions.h"
// main.c
#define EXTERN
#include "functions.h"
When main compiles, storage will be allocated for number. In all other source files, it will be declared as extern.
A toy code illustrating my problem is as follows:
stuff.h:
#ifndef STUFF
#define STUFF
int a;
int testarr[]={1,2,3};
#endif
fcn.h:
#include "stuff.h"
int b[]={5,6,7};
void fcn();
main.h:
#include "stuff.h"
#include <stdio.h>
fcn.c:
#include "main.h"
void fcn() {
printf("Hello\n");
}
main.c:
#include "main.h"
#include "fcn.h"
int main() {
fcn();
printf("HI\n");
}
An attempt to compile fails with:
/g/pe_19976/fcn_2.o:(.data+0x40): multiple definition of `testarr'
/g/pe_19976/main_1.o:(.data+0x40): first defined here
After doing some reading, I realize that defining the array testarr in the header file is a problem. But the thing is, in my real code, several files need access to testarr and it needs to have the same assigned values everywhere. I guess I could put it in main.h (?) but even if that would work, in my real code it logically belongs in stuff.h. How do I solve this conundrum?
BTW, based on something else I found, I tried defining testarr as extern but got the same problem.
When you put a variable definition into a header file, any .c file that includes it will have a copy of that variable. When you then attempt to link them, you get a multiple definition error.
Your header files should contain only a declaration of the variable. This is done using the extern keyword, and with no initializer.
Then in exactly one .c file, you put the definition along with an optional initializer.
For example:
main.c:
#include "main.h"
#include "fcn.h"
int a;
int testarr[]={1,2,3};
int main() {
fcn();
printf("HI\n");
}
stuff.h:
#ifndef STUFF
#define STUFF
extern int a;
extern int testarr[];
#endif
fcn.h:
#include "stuff.h"
extern int b[];
void fcn();
fcn.c:
#include "main.h"
int b[]={5,6,7};
void fcn() {
printf("Hello\n");
}
It is not clear why you are using so many global variables. The array
int testarr[]={1,2,3};
is defined as many times as there are compilation units (in your example there are at least two compilation units) that include the corresponding header.
Declare the array in a header like
extern int testarr[3];
and define it in a cpp module.
int testarr[]={1,2,3};
The same is valid for other global variables that have external linkage.
As for this remark
BTW, based on something else I found, I tried defining testarr as
extern but got the same problem.
Then the array with the specifier extern shall not be initialized in a header. Otherwise it is a definition of the array.
Eclipse tells me that I have mutliple Definitions of a function.
I just can't spot the mistake.
This is my main.c
#include <stdio.h>
#include "kontaktverzeichnis.h"
int main(){
kontakt_hinzufuegen();
return 0;
}
This is the header:
#ifndef KONTAKTVERZEICHNIS_H_
#define KONTAKTVERZEICHNIS_H_
#include "kontaktfunktionen.c"
int kontakt_hinzufuegen();
#endif /* KONTAKTVERZEICHNIS_H_ */
and this is kontaktfunktionen.c
#include <stdio.h>
kontakt[];
kontakt_hinzufuegen(){
int i = 0;
printf("Bisher sind %i Kontakte angelegt.",kontakt[i]);
kontakt[i++];
}
struct kontaktname{
char* name;
char* vorname;
};
struct kontaktanschrift{
char* strasse;
int hausnummer;
int plz;
char* ort;
char* land;
};
Where is my error?
You're not supposed to #include C files, that's not the proper way to organize your code.
You should compile the C files separately and then link them together, or compile them all at once with a single compiler invocation.
Do not #include anything in your header file. And do a #include "kontaktverzeichnis.h" in the kontaktfunktionen.c file.
As #StoryTeller commented, define your kontakt_hinzufuegen() as int kontakt_hinzufuegen() in the kontaktfunktionen.c file and return an int value from the function kontakt_hinzufuegen as for ex::
#include <stdio.h>
#include "kontaktverzeichnis.h"
// define the type for this array as below
int kontakt[];
int kontakt_hinzufuegen(){
int i = 0;
printf("Bisher sind %i Kontakte angelegt.",kontakt[i]);
kontakt[i++];
// Return an int value
return 0 ;
}
Your error is that in kontaktfunktionen.h you are including kontaktfunktionen.c. This will include all the definitions and declarations from kontaktfunktionen.c which are already declared when you use kontaktfunktionen.c
As others have said: You should not include .c files in your header files.
Error 2 error C2371: 'QixC': redefinition; different basic types line 5
Error 5 error C2371: 'QixC': redefinition; different basic types line 5
Error 13 error C2371: 'QixC': redefinition; different basic types line 5
This is the part of the file Game.h:
#include "Graphics_Console.h"
#include <stdio.h>
#include <conio.h>
typedef struct
{
int X;
int Y;
}QixC;
typedef struct
{
int X;
int Y;
}CCursor;
And I use them in Game.c :
#include "Game.h"
#include <stdio.h>
#include <conio.h>
#include <time.h>
int QIX(int nivell)
{
QixC Qix;
CCursor Cursor;
HANDLE hScreen;
int DirQixX,DirQixY;
int IniciX,IniciY;
int FiX, FiY;
int DirStix=0;
int Area=0,AreaTotal=0,AreaObjectiu=(FI_X-INICI_X)*(FI_Y-INICI_Y)*0.75;
int Pantalla=1;
int Puntuacio=0;
int tecla=0;
int viu=1;
int NCops=0, Velocitat=1000/(nivell*0.70);
int XocStix=0;
char continuar[1];
hScreen = GetStdHandle(STD_OUTPUT_HANDLE);
InitScreen(hScreen);
do
{
system("CLS");
IniciX=INICI_X,IniciY=INICI_Y;
FiX=FI_X, FiY=FI_Y;
Cursor.X=INICI_X+(FiX-INICI_Y)/2,Cursor.Y=FI_Y;
DibuixarRectangle(IniciX,IniciY,FI_X,FI_Y,hScreen);
InfoPuntsPartida(hScreen, Puntuacio);
InfoPantallaPartida(hScreen, Pantalla);
Qix.X=Aleatori(IniciX+1,FiX-1),Qix.Y=Aleatori(IniciY+1,FiY-1);
InicialitzarDirQix(&DirQixX,&DirQixY);
PintarQix(Qix,hScreen);
PintarCursor(Cursor.X,Cursor.Y,hScreen);
do{
if(_kbhit())
{
tecla=LlegirEvent();
TractarEvent(tecla,Cursor,&IniciX,&IniciY,&FiX,&FiY,Qix,&DirStix,&Area,hScreen);
if(Area)
{
Puntuacio=Puntuacio+Area;
AreaTotal+=Area;
Area=0;
InfoPuntsPartida(hScreen,Puntuacio);
}
}
NCops++;
if(NCops==Velocitat)
{
if(DirStix!=0)
XocStix=QiXXocStiX(Qix,Cursor,DirStix);
if(!XocStix)
MoureQix(Qix,&DirQixX,&DirQixY,IniciX,IniciY,FiX,FiY,hScreen);
else
viu=0;
NCops=0;
}
}while((tecla!=TECLA_q)&&(tecla!=TECLA_Q)&&viu &&(AreaTotal<AreaObjectiu));
GameOver(hScreen);
TextColor(LIGHTGREY,BLACK,hScreen);
GotoXY(0,FI_Y+1,hScreen);
return Puntuacio;
system ("PAUSE");
printf("Continuar?(s/n)");
scanf("%c",&continuar);
}while(continuar!="s");
}
Sorry for the foreign words and names, english is not my first language.
I can't see where is redefined. They don't appear anywhere else,but are passed as parameters to some functions. Any help, please?
Try guarding your header against multiple inclusion.
#ifndef GAME_H
#define GAME_H
#include "Graphics_Console.h"
#include <stdio.h>
#include <conio.h>
typedef struct
{
int X;
int Y;
}QixC;
typedef struct
{
int X;
int Y;
}CCursor;
#endif /* GAME_H */
By default, if you include multiple headers which directly or indirectly include your header, you'll get multiple competing (if identical) versions of its structures and functions. You can avoid this by starting your header
#ifndef SOMETHING_UNIQUE_TO_YOUR_HEADER
#define SOMETHING_UNIQUE_TO_YOUR_HEADER
and ending it
#endif /* SOMETHING_UNIQUE_TO_YOUR_HEADER */
which guarantees that any source file will include at most a single copy of your structures.