Compile error on using extern - c

I wrote a very simple program on C. It compiles and works fine. But if I add extern int x at the functions.h instead of functions.c I get this error
functions.c:3:12: error: use of undeclared identifier 'x'
return x / 2;
^
1 error generated.
I thought the correct place for extern is in the header file.
variables.h
int x = 10;
functions.h
#include "variables.h"
int calculate_items(int d);
functions.c
extern int x;
int calculate_items(int d)
{
return x / 2;
}
main.c
#include <stdio.h>
#include "functions.h"
int main() {
printf("%d", calculate_items(5));
}

No, you can't have an initializer in the header.
It will not work as soon as more than one C file include the same header, there will be multiple declarations.
You should make the variable a global in one of the C files, for instance in main.c, and then just have extern int x; in the files that need to access it (or in headers that they can #include, of course).
In this case, since the variable ends up "belonging to" the main.c file, you should probably add a main.h header that has the extern int x; declaration, and #include that from functions.c and other places that need the variable.

If you don't put extern int x; in functions.c and functions.c doesn't #include anything that declares x, how is it supposed to know what x is?
If you expect some kind of implicit relationship between functions.h and functions.c because they both have names like functions.* then you should just get rid of that expectation.
The normal way to do this is to put the extern int x; in functions.h, then int x=10; in one of the .c files, and #include "functions.h" from all of the .c files that reference x, including functions.c.

Related

Confusion about the extern keyword and multiple source files

I am trying to fully understand how extern works, so I created 3 files, two of them are source files and the last is a header file. This is what is contained in each of them:
testingfile1.c
#include <stdio.h>
#include "testingheader.h"
int main() {
change();
int my_extern;
printf("\n%d", my_extern);
return 0;
}
testingfile2.c:
#include <stdio.h>
#include "testingheader.h"
void change() {
int my_extern;
my_extern = 15;
printf("%d", my_extern);
}
testingheader.h:
#if !defined(TESTINGHEADER_H)
#define TESTINGHEADER_H
#include <stdio.h>
extern int my_extern;
void change();
#endif
The output of this program is: 15 0. However, I thought that since my_extern is an extern int, if you were to change to the value in one source file, it's value would be changed in all of the other source files. Is this not how extern works, or am I doing something wrong in the code itself?
In both cases remove int my_extern; where you have it, because those become local variables which happen to have the same name my_extern.
extern int my_extern; just means there's an int called my_extern "out there somewhere". So you'd have to declare int my_extern somewhere at file scope, for example like this:
int my_extern = 0;
void change() {
my_extern = 15;
printf("%d", my_extern);
}
In testingfile2.c, the my_extern variable is local to the function and you are not seeing the global my_extern that the extern command is referencing. Of course, you don't have a global my_extern, so that is another problem. You would get a linker error if you actually tried to reference the global my_extern that the extern command is referencing.
The issue is you're re-declaring int my_extern; inside your functions. Therefore, C treats that as a separate variable from the global my_extern.
The statement extern int my_extern; is a declaration that a global int called my_extern will be declared somewhere. You haven't done that. Instead, you've created local my_extern variables.

Understanding how extern works

The way I understand extern is that we are able to declare a variable anywhere in a program and use it, but we can just define it once. I am getting an error in the following program.
hello.c
#include <stdio.h>
#include "function.h"
extern int c;
int main()
{
int c;
c=10;
printf("%d\n",c);
printExternValue();
return 0;
}
function .h
void printExternValue();
function .c
#include "function.h"
#include "stdio.h"
extern int c;
void printExternValue()
{
printf("%d\n",c);
}
I expect this program to print out:
10
10
But it's not doing so since it's giving an error. I re-declared the variable c in the function.c file with the intention of using the value that is stored in the so called external storage.
Error: function.c:(.text+0x6): undefined reference to `c'
I am currently reading a PDF file from tutorialspoints which I think to be very redundant since the intention of creating a variable with the aggregate extern is useless. The right way this should be done is that they define the variables outside the function is that right?
#include <stdio.h>
// Variable declaration:
extern int a, b;
extern int c;
extern float f;
int main ()
{
/* variable definition: */
int a, b;
int c;
float f;
/* actual initialization */
a = 10;
b = 20;
c = a + b;
printf("value of c : %d \n", c);
f = 70.0/3.0;
printf("value of f : %f \n", f);
return 0;
}
Variable declread as
extern int c;
is an external declaration that potentially requires an external definiton. "External" in this case means "located outside of any function". Your c declared locally in main() does not fullfill that role.
Since you are using that externally declared variable c in your code you have to define it and define it only once.
You need
int c;
or
int c = 0;
or
extern int c = 0;
it one of your implementation files, at file scope. All of these are definitions. Any of them will define your variable.
Define your variable once in one of your files (to reserve space),
int c = 0;
Declare your variable references everywhere else (in all of your other files) (to reference said space),
extern int c;
But that could be confusing, so name them indicative of the 'global' use,
int glob_a, glob_b;
int glob_c;
float glob_f;
And declare your variable references everywhere else,
extern int glob_a, glob_b;
extern int glob_c;
extern float glob_f;
But you really want to avoid littering you namespace, so when you have a collection of globals, declare a struct that contains them (in a header file probably called globals.h),
typedef struct globals_struct {
int a, b;
int c;
float f;
} globals_t;
And once (in your file main.c that declares main()), you define the struct,
#include globals.h
globals_t globs;
And everywhere else, reference the space,
#include globals.h
extern globals_t globs;
Often, you will see a stanza such as this, where MAIN is only declared in one file,
#ifndef MAIN
extern globals_t globs;
#else
globals_t globs;
#endif
Use your globals,
int my_a = globs.a;
int my_b = globs.b;
int my_f = globs.f;
Notice how you have avoided needless namespace pollution?
Because extern just tells the compiler (actually the linker) that a variable is being defined elsewhere and needs to be linked against.

variable between files [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How do I share variables between different .c files?
If I have two source files, and one header: file1.c, file2.c, and header.h, and:
--header.h--
int i;
--file1.c--
#include <header.h>
i = 10;
int main() {
func();
return 0;
}
--file2.c--
#include <header.h>
void func() {
printf("i = %d\n", i);
return;
}
I get the warning that i defaults to an int. What could I do if I want to have i as a float for instance?
Make it
extern int i;
in the header and
int i = 10;
in file1.c.
The warning means that for the (incomplete) declaration i = 10; in file1.c, the "implicit int" rule is applied, in particular, that line is interpreted as a declaration (since an assignment cannot appear outside function scope).
You have a couple of errors in your code. The first is that you define the variable i in the header file, which means that it will be defined in all source files that include the header. Instead you should declare the variable as extern:
extern int i;
The other problem is that you can't just assign to variables in the global scope in file1.c. Instead it's there that you should define the variable:
int i = 10;
Declare it as extern in the header (this means memory for it is reserved somewhere else):
/* header.h */
extern int i;
Then define it in only one .c file, i.e. actually reserve memory for it:
/* file1.c */
int i = <initial value>;
In the header use
extern int i;
in either file1.c or file2.c have
int i = 20;
If you want float just change int to float
In 99.9% of all cases it is bad program design to share non-constant, global variables between files. There are very few cases when you actually need to do this: they are so rare that I cannot come up with any valid cases. Declarations of hardware registers perhaps.
In most of the cases, you should either use (possibly inlined) setter/getter functions ("public"), static variables at file scope ("private"), or incomplete type implementations ("private") instead.
In those few rare cases when you need to share a variable between files, do like this:
// file.h
extern int my_var;
// file.c
#include "file.h"
int my_var = something;
// main.c
#include "file.h"
use(my_var);
Never put any form of variable definition in a h-file.

About accessing structs defined in different source file

Not any homework, but seem to have got lost while doing basics, hence asking.
Say I have 2 C source files. 1.c & 2.c
2.c is as follows:
typedef struct mystr_
{
int a;
float b;
}mystr;
void fun()
{
mystr q;
some code....
}
And 1.c is as below:
#include "stdio.h"
void fun();
main()
{
//How to access / declare a variable of type mystr here.
mystr *v1;//This obviously gives compiler errors
some code....
}
How to access the structure mystr defined in 2.c from file 1.c to have variables of that struct type there?
EDIT:
Sorry forgot to mention in OP. I cannot move the declaration out in a header file for some reason --> It is a quick hack that I am trying to check in a existing code. Then is there any way to access it directly from the other source file?
Use headers.
Create a file 2.h
typedef struct mystr_
{
int a;
float b;
}mystr;
And include it in 1.c
#include "2.h"
#include "stdio.h"
void void fun();
EDIT:
Because you are not able to extract the declaration into a header file and include it, there is no other way than copying the declaration. This is a highly fragile construct, quick but mainly dirty and not really recommended unless you are out of other options.

How do I share a global variable between c files?

If I define a global variable in a .c file, how can I use the same variable in another .c file?
file1.c:
#include<stdio.h>
int i=10;
int main()
{
printf("%d",i);
return 0;
}
file2.c:
#include<stdio.h>
int main()
{
//some data regarding i
printf("%d",i);
return 0;
}
How can the second file file2.c use the value of i from the first file file1.c?
file 1:
int x = 50;
file 2:
extern int x;
printf("%d", x);
Use the extern keyword to declare the variable in the other .c file. E.g.:
extern int counter;
means that the actual storage is located in another file. It can be used for both variables and function prototypes.
using extern <variable type> <variable name> in a header or another C file.
In the second .c file use extern keyword with the same variable name.
Do same as you did in file1.c
In file2.c:
#include <stdio.h>
extern int i; /*This declare that i is an int variable which is defined in some other file*/
int main(void)
{
/* your code*/
If you use int i; in file2.c under main() then i will be treated as local auto variable not the same as defined in file1.c
Use extern keyword in another .c file.
If you want to use global variable i of file1.c in file2.c, then below are the points to remember:
main function shouldn't be there in file2.c
now global variable i can be shared with file2.c by two ways:
a) by declaring with extern keyword in file2.c i.e extern int i;
b) by defining the variable i in a header file and including that header file in file2.c.

Resources