This question already has answers here:
How do I use extern to share variables between source files?
(19 answers)
Closed 6 years ago.
I am trying to declare an variable x in a file demo_f1.c and use it in two files demo_f2.c and demo_f3.c having two functions void f2() and void f3(), respectively.
I have a driver program that uses the variable x and both of these functions, but it gives me an error while I try to compile the driver program.
demo_f1.c
int x=2;
demo_f2.c
#include"C:\TC\BIN\demo_f1.C"
void f2()
{
extern int x;
printf("In f2 x:%d\n",x);
}
demo_f3.c
#include"C:\TC\BIN\demo_f1.C"
void f3()
{
extern int x;
printf("In f3 x:%d\n",x);
}
Driver.c
#include"stdio.h"
#include"conio.h"
#include"C:\TC\BIN\demo_f1.C"
#include"C:\TC\BIN\demo_f2.C"
#include"C:\TC\BIN\demo_f3.C"
void main()
{
clrscr();
printf("In main program,x:%d\n",x);
f2();
f3();
getch();
}
The error:
Compiling C\TC\BIN\Driver.C:
Error C\TC\BIN\DEMO_F1.C 1: Variable 'x' is initialized more than once
Error C\TC\BIN\DEMO_F1.C 1: Variable 'x' is initialized more than once
Why am I getting this error? How can I correct it?
To make your code compile, you simply need to remove extern int x; from f2() and f3(). For a more complete answer read How do I use extern to share variables between source files in C? as grahamj42 suggests.
You are including demo_f1.c three times in driver.c, one directly and two indirectly through demo_f2.c and demo_f3.c. In consequence, the compiler finds three times the line "int x=2;"
You can use the mechanism with #ifndef typically used in header files. Make demo_f1.c like this:
#ifndef DEMO_F1_C
#define DEMO_F1_C
int x=2;
#endif
Alternatively, to avoid including the .c file, you could have:
demo_f1.h
#ifndef DEMO_F1_H
#define DEMO_F1_H
extern int x;
#endif
demo_f1.c
#include "demo_f1.h"
int x = 2;
And the other files would include demo_f1.h.
Related
I have a project that includes three files in codeblocks:
main.c :
#include <stdio.h>
#include <conio.h>
int global = 10;
void f1(int);
void f1_1(int);
void f2(void);
int main()
{
int x = 5;
printf("inside main file");
getch();
f1(x);
f2();
getch();
return 0;
}
file1.c :
#include <stdio.h>
#include <conio.h>
void f1(int x)
{
printf("\ninside file1 >> f1 and x = %i", x);
getch();
f1_1(x);
}
void f1_1(int x)
{
printf("\ninside file1 >> f1 >> f1_1 and x = %i", x);
getch();
}
file2.c :
#include <stdio.h>
#include <conio.h>
extern int global;
void f2()
{
printf("\ninside file2 >> f2 function , global var = %i", global);
getch();
}
When I compiled it, I got these warnings:
c|8|warning: implicit declaration of function 'f1_1'; did you mean 'f1'? [-Wimplicit-function-declaration]
c|11|warning: conflicting types for 'f1_1'
What should I do for this?
void f1(int);
void f1_1(int);
void f2(void);
Should be:
extern void f1(int);
extern void f1_1(int);
extern void f2(void);
Or, as #kiranBiradar points out, you can declare them in header files
file1.h
#pragma once
extern void f1(int);
extern void f1_1(int);
file2.h
#pragma once
extern void f2(void);
Note the use of the extern keyword. When you forward declare a function in a file as void f(void), the symbol 'f' is public, meaning other compilation units can reference it. When you declare it as extern void f(void), then the compiler doesn't expect the function to be defined in that compilation unit and leaves it up to the linker to find that symbol.
This is the perfect time to learn about the important concept of translation units.
Each single source file, with all included header file, forms a single translation unit. Each translation unit is separate and distinct and compiled stand-alone without any knowledge of other translation units.
That means symbols declared in e.g. the main.c source file will not be known in the file1.c source file.
When you compile file1.c the compiler simply doesn't know about the f1_1 function declaration you have in the main.c source file, so you get a warning about that fact.
To solve your problem, you need to declare the f1_1 function in the file1.c file. Either by adding a forward declaration (like the one you have in main.c), or moving the whole function definition (implementation) of f1_1 above the f1 function.
Or you could create a single header file which contains all the declarations needed (for the f1, f1_1, f2 function, plus the global external variable declaration), and include this single header file in all your source files. This solution works best if you have multiple symbols (functions, variables, etc.) that are used in multiple translation units.
My personal recommendation is this: Since the f1_1 function is only used internally inside the file1.c source file, move its definition above f1, and make it static. Then remove its declaration from the main.c source file.
Regarding the "implicit declaration" and "conflicting types" warnings, it's because in older standards of C it was allowed to not declare functions and the compiler would create an implicit declaration by guessing the declaration based on the first call of the function.
The important part about the guessing is that only the arguments were guessed, the return type would always be int.
I don't know the exact wording in the specifications about this since it was removed in the C99 specification, but most compilers still allow this with only emitting a warning instead of an error. This is where the first warning comes from.
However, the return type of int is still being used. And since your f1_1 function is declared to return void later in the file1.c source file, there's a mismatch between the guessed declaration (int f1_1(int)) and the actual declaration (void f1_1(int)) which leads to the second warning.
I have following three files. In the header file, I declare a global variable and tried to access it other files using extern. But I got the linker errors.
Header1.h
#ifndef HEADER1_H
#define HEADER1_H
#include<stdio.h>
int g = 10;
void test();
#endif
test.c
#include "header1.h"
extern int g;
void test()
{
printf("from print function g=%d\n", g);
}
main.c
#include "header1.h"
extern int g;
int main()
{
printf("Hello World g=%d\n", g);
test();
getchar();
return 0;
}
Linker error:
LNK2005 "int g" (?g##3HA) already defined in main.obj
LNK1169 one or more multiply defined symbols found
My understanding about extern is that a variable can be defined only once but can be declared multiple times. I think I follow it this way - I defined the global variable g in the header file and tried to access it in the .c files.
Could you please correct my understanding? What actually causes the linker error here? I did not define g multiple times.
You get a multiple definition error because you put the definition in the header file. Because both source files include the header file, that results in g being defined in both places, hence the error.
You want to put the declaration in the header file and the definition in one source file:
In header1.h:
extern int g;
In test.c:
int g = 10;
And nothing in main.c.
Hello (sorry for my bad english).
During my free time, I am doing a little application in python (3.5).
This application will have to call functions from a DLL made in C. I succeed to do it but I have a more "general" question. Let's take an example. I have four functions in my C code :
goNorth() {y++;}
goSouth() {y--;}
goWest() {x--;}
goEast() {x++;}
Easy to understand, just x and y coordinate, each function makes a move. My question is : Is there an easy way (and clean) to share the x and y betwwen all functions if I made a dll of this code ?
Julien
Yes, it is. Define the variable in an "implementation" file, and declare it as "extern" in a header file:
Implementation file:
// mylib.c
#include "mylib.h"
int x;
int y;
void goNorth() { ... }
void goSouth() { ... }
Headerfile:
// mylib.h
extern int x;
extern int y;
void goNorth();
void goSouth();
This question already has answers here:
Header per source file
(7 answers)
Closed 5 years ago.
when i'm reading some tutorial in C programming,all of them said that we need to put only structure type declarations, function prototypes, and global variable extern declarations, in the .h file; and for the function definitions and global variable definitions and initializations we need to put them in the .c file.
but when i try to put the content of the function in the header file it works fine. if it works fine why we must not use it ?
in the sum.h :
#ifndef HEADER_H_INCLUDED
#define HEADER_H_INCLUDED
#include<stdio.h>
#include<stdlib.h>
int sum(int a,int b)
{
return a+b;
}
#endif // HEADER_H_INCLUDED
int the main.c:
#include "sum.h"
int main()
{
printf("%d\n",sum(1,2));
return 0;
}
Broadly, you might what to include your header in multiple source files. If you have actual function definitions in there, you're going to have multiple definitions. This will be fine until the linker tries to assemble your compiled sources into an executable or library, at which point it will fail because it finds several functions with the same name.
I created a program in C that can find the determinant of a matrix
void fun1(); /*regardless of parameters they take*/
void fun2();
void fun3();
void fun4();
void fun5();
int global_var1; /*they are used among the above functions*/
int global_var2;
int global_var3;
int determinant;
int main(void){
int x,y;
for(x=0; x<something ; x++){
for (y=0 ; y<another_thing; y++){
fun1();
fun2();
fun3();
}
fun4();
fun5();
}
printf("Determinant is: %d\n", determinant);
return 0;
}
void fun1(){/*code goes here to process the matrix*/;}
void fun2(){/*code goes here to process the matrix*/;}
void fun3(){/*code goes here to process the matrix*/;}
void fun4(){/*code goes here to process the matrix*/;}
void fun5(){/*code goes here to process the matrix*/;}
Now I need to use this program to find the determinant of a given matrix in another project.
I created a header file, named it "matrix.h" and I replaced the int main(void) with int find_determinant() to be used in the new project.
the prototype of the second program:
#include "matrix.h"
int main(void){
find_determinant(); /*regardless of para it takes, it works perfectly*/
return 0;}
it works properly, nothing wrong with it, but the only problem that if I want to give this header file "matrix.h to someone to use it in his program, he can know the signature of other functions (useless for him alone and confusing) that were used to help in finding the determinant in int find_determinant().
My question is:
How can I hide (make them inaccessible) those functions and global variables and show only the int find_determinant() function in the second C file/program that contains #include "matrix.h" ?
Although you can put executable code in a header file, a good practice is to have your header file only contain declarations (for global variables) definitions and function prototypes. If you don't want to give your source code implementation, then you need to compile your functions into object code and provide the object file (either as a static archive or shared library) along with the header file. Whoever wants to use your function will then link his/her program to your objecet file/shared lib. This way, you can keep your source code implementation to yourself. Your header file would be:
#ifndef __SOME_MACRO_TO_PREVENT_MULTIPLE_INCLUSION__
#define __SOME_MACRO_TO_PREVENT_MULTIPLE_INCLUSION__
int find_determinant();
#endif
Beware of multiple inclusion problems (I have shown above how to avoid this so that if your matrix.h file is included several times, programs will still compile).