Multiple Definition of a function in C, Prototyping - c

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.

Related

Define a variable in header file works only when extern keyword is not present? [duplicate]

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.

C header files without #ifndef still work...why? [duplicate]

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.

need a workaround for a "multiple definition" error

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.

Functions from header file not working without including .c too

I try to make program in C and I cant use functions from .h without including .c file too. If I include .c after including .h it works. I get "undefined reference to ..." error on every function defined in .h.
main.c:
#include "mp.h"
//#include "mp.c"
int main()
{
int n;
printf("Unesite broj clanova niza: ");
scanf("%d",&n);
int *a=(int *)malloc(n*sizeof(int));
if (a==NULL) exit(0);
unos(a,n);
sortiranje(a,n,rastuci);
stampanje(a,n);
sortiranje(a,n,opadajuci);
stampanje(a,n);
return 0;
}
mp.h:
#ifndef MP_H_INCLUDED
#define MP_H_INCLUDED
#include <stdio.h>
#include <stdlib.h>
enum tip_sort {opadajuci,rastuci};
void unos(int *, int);
void sortiranje(int *, int, enum tip_sort);
void stampanje(int *, int);
#endif // MP_H_INCLUDED
mp.c:
#include "mp.h"
void unos(int *a, int n){
...
}
void sortiranje(int *a, int n, enum tip_sort t){
...
}
void stampanje(int *a, int n){
...
}
What you're seeing is a linker error. I guess, you're trying to compile main.c all alone.
You compilation statement should look like
gcc main.c mp.c -o output
and yes, do not #include .c (source) files. Source files are meant to be compiled and linked together to form the binary.
Note: Also, please do not cast the return value of malloc().

C Static Function Confusion

I am trying to make the s_cord_print function visible in the cord_s.c file only. Currently the function is visible/runnable in main.c even when it is declared static.
How do I make the s_cord_print function private to cord_s.c?
Thanks!
s_cord.c
typedef struct s_cord{
int x;
int y;
struct s_cord (*print)();
} s_cord;
void* VOID_THIS;
#define $(EL) VOID_THIS=&EL;EL
static s_cord s_cord_print(){
struct s_cord *THIS;
THIS = VOID_THIS;
printf("(%d,%d)\n",THIS->x,THIS->y);
return *THIS;
}
const s_cord s_cord_default = {1,2,s_cord_print};
main.c
#include <stdio.h>
#include <stdlib.h>
#include "s_cord.c"
int main(){
s_cord mycord = s_cord_default;
mycord.x = 2;
mycord.y = 3;
$(mycord).print().print();
//static didn't seem to hide the function
s_cord_print();
return 0;
}
~
The problem is:
#include "s_cord.c"
You should remove that. Instead, create a s_cord.h file that contains only declarations, such as:
typedef struct s_cord{
int x;
int y;
struct s_cord (*print)();
} s_cord;
and put:
#include "s_cord.h"
in main.c and s_cord.c. You also need an extern declaration for s_cord_default. So the complete code is:
s_cord.c:
#include "s_cord.h"
#include <stdio.h>
void* VOID_THIS;
static s_cord s_cord_print(){
struct s_cord *THIS;
THIS = VOID_THIS;
printf("(%d,%d)\n",THIS->x,THIS->y);
return *THIS;
}
const s_cord s_cord_default = {1,2,s_cord_print};
s_cord.h:
typedef struct s_cord{
int x;
int y;
struct s_cord (*print)();
} s_cord;
#define $(EL) VOID_THIS=&EL;EL
extern const s_cord s_cord_default;
extern void *VOID_THIS;
main.c:
#include <stdio.h>
#include <stdlib.h>
#include "s_cord.h"
int main(){
s_cord mycord = s_cord_default;
mycord.x = 2;
mycord.y = 3;
$(mycord).print().print();
return 0;
}
You'll now get a error if you try to call s_cord_print() from main, as expected.
EDIT: I forgot to move the $(EL) definition, and it needed an extern for VOID_THIS.
EDIT 2: The correct compilation command is:
gcc s_cord.c main.c -o main
When you include s_cord.c from within main.c, the compiler sees your program as one big file. It doesn't treat the included file as separate. To make them separate, you have to compile them separately. Once you have compiled them separately, you will then have to link them to create the whole program.
When you try to compile each part, you will get errors, because each file doesn't know about the code in the other file. Remember, this is what you were trying to accomplish with that one function. Well, now you've got what you asked for, many times over. Now, you have to create header files that explain the "missing parts". Generally the files being compiled look at each other's ".h" files (they #include them) to get a bearing on the "missing" (actually, external) parts. These are declarations, which tell the compiler "pretend you already know about this, and I promise that when we link everything, it will be provided".

Resources