Sharing variables across files in C - c

I have two files:
hudwidgets.c
#include "osd.h"
#include "osdadd.h"
#include <stdio.h>
struct TextSize tsize;
char buff[50];
void hud_draw_lin_compass(int cx, int cy, int tick_maj, int tick_min, int range, int heading)
{
.. important code that uses buff ..
}
hud.c
#include "hudwidgets.h"
#include "hud.h"
#include "osd.h"
#include "osdadd.h"
.. some code ..
void hud_rc_plane_single_frame()
{
fill_mem(0x0000);
if((frame / 50) % 2 == 0)
{
get_next_warning(buff);
}
.. some more code ..
}
The problem I have is that when I try to compile this, the compiler complains of no buff defined, but when I try to define it, the linker complains of two buff variables. Catch-22. To this end, I am asking two questions:
how to fix this, and;
if it is possible to use the same variable thus saving memory because only one variable needs to be allocated (working with a memory constrained microcontroller.)

You need this in the top of hud.c, and any other .c file you use them from:
extern struct TextSize tsize;
extern char buff[50];
The extern keyword tells the compiler that the "actual" variables already exist, in some other unit (file), and the linker will fix it all up for you in the end.
If you're doing this on a large scale in a project, consider how you might encapsulate globals in one place, and create a shared .h file that declares these things as "extern" for all the places that you use them from.

use "extern char buff[50];" in the files where you have not initialized the buff and want to use it. This tells that the declaration is done in other files and you are using it in this file.

Related

global static(or non-static?) char array(buffer) with access from all c files

I have a header file , "temp.h" ,and several ".c" files which has "#include <temp.h>" header statements in each of them. And I define a global static char array in "temp.h" file as follows:
temp.h
static char buffer[1000]={'A','B','C','\0'};
main.c
...
#include <temp.h>
int main()
{
strcpy(buffer,"xyz");
printf("\nBuffer : %s",buffer);
func();
return 0;
}
other.c
...
#include <temp.h>
int func()
{
printf("\nInside func(), buffer : %s",buffer);
return 0;
}
and I compile all files with following command:
gcc -o output.o main.c other.c
And I get no errors... and when run the "output.o" program ,
I expect a result like this:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : xyz
but I get:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : ABC // doesn't get updated buffer content- why?
Why when I change the contents of a "(supposedly)global" static char array in one file inside any function scope (main or anyother), this change doesn't get reflected to all this char array's future references from any other file later, but instead in each file((or maybe inside in each function) its content is preserved??
How to make such that, I can use a specific part of char array (memory region) which is GLOBALLY accessible from all "files" and in their functions, and all references get correct readings?
thnx
With your current approach you have two copies of the array. Instead you need to declare the array in temp.h (with extern instead of static) and define it elsewhere, for instance in in temp.c:
temp.h:
#ifndef TEMP_H
#define TEMP_H
extern char buffer[1000];
#endif
temp.c:
#include "temp.h"
char buffer[1000] = "ABC";
You can also probably find a more descriptive name than temp for the module. It is also a good idea to add a prefix to the buffer variable, e.g. temp_buffer so that you avoid potential name clashes and make it easier for yourself and others to find where the array is declared.
Ok...GOT IT!... now I solved!
In a singly included header file (( which is temp.h in question )) u must write:
extern char buffer[];
Note: single inclusion of this temp.h file can be achieved by "#ifndef-#endif" pairs in other ".c" and ".h" files of the compilation.
And next, include only in one of the files the following statement of definition:
char buffer[1000];
I hope this solution helps some guys.

Configurations variables removed by compiler

I am attempting to define a set of global variables which will configure my device, about 10 in a dedicated .c file, that will be changed on a regular basis at compile time (as per device requirements), I want these to be in this separate file so they can all be changed easily. These variables are then called throughout my program in various files. And are never changed only read. The problem is that my compiler (XC8 for PIC MCU's) doesn't define the variable, as it can only see that one use of the variable in the file, even though it is called with extern throughout the program.
config.h
unsigned int Global_A;
unsigned int Global_B;
void config(void);
config.c
void config(void)
{
unsigned int Global_A=987;
unsigned int Global_B=123;
}
prog_a.h
extern unsigned int Global_A;
extern unsigned int Global_B;
unsigned int var_A;
void prog_a(void);
prog_a.c
unsigned int var_A=0;
void prog_a(void);
{
var_A=Global_A+Global_B;
}
main.c
#include config.h
#include prog_a.h
void main(void)
{
while(1)
{
config();
prog_a();
}
}
as a result, the equivalent var_A is always 0, as the compiler has done away with config.c as it cannot see the variable called again.
I'm assuming the answer is very obvious to those more versed, but I can't find anything online. I have not had any trouble with using extern and globals before when they are used in the file the are defined in. But I could just be using it wrong fundamentally, so feel free to berate me.
Thanks in advance.
p.s if it wasn't obvious this is an example code to illustrate my problem.
Your function config declares two new variables in the scope of the function (their names hide those of the global variables). They don't exist anywhere outside of it, and assigning a value to them does nothing. If your goal was for it to initialize the globals, you need do this:
// config.h
extern unsigned int Global_A;
extern unsigned int Global_B;
void config(void);
// config.c
unsigned int Global_A;
unsigned int Global_B;
void config(void) {
Global_A=987;
Global_B=123;
}
With extern keyword it it necessary to declare the variable once (preferably in a header file) define it once in a .c file that has visibility to the declaration statement. That is it. Where the extern defined variable is necessary, #include the header file in which the declaration statement occurred.
Also note it is important also to define extern variable(s) in global scope (i.e. not in a function).
config.h:
#include "prog_a.h"
//unsigned int Global_A;
//unsigned int Global_B;
void config(void);
main.c
#include config.h
#include prog_a.h
...
//suggest defining these here:
unsigned int Global_A=0;//define outside of function
unsigned int Global_B=0;
...
config.c
#include "prog_a.h"
...
void config(void)
{
Global_A=987;
Global_B=123;
}
Your global variables are all of type int, so why not just use #define?
Change file config.h to
#define Global_A 789
#define Global_B 123
You do not actually have to declare any int variables to hold those values, plus, they will be const and unmodifiable.
That's they way that we did it "back in the day", but in the last decade or two, I see more and more actually storing these configuration values in an external text file
It can be a .INI, or XML or JSON, etc, etc, that is up to you.
You just create different files, let's say Singapore.ini and Paris.ini and Auckland.ini, etc, each containing a key/value pair.
e.g
time_zone = X
population = Y
etc, etc
Then, at the start of your main, read the file in and store the values -but not in globals, which are frowned upon, these days. Read them into variables which are local to config.c, and have config.c/h provode methods to read their values, e.g GetTimeZone() and GetPoulation(), etc
Don't worry about any code size or run time impact of this, as any decent compiler will in-line these function calls.
One advantage to reading "global" configuration values in an external text file is that you only need to build your software once. You do not need to rebuild and have an executable for each configuration, which the road that you are currently heading down.
Firstly, this makes it easier to test your software (especially automated test), by merely editing the text file, or supplying a new one.
Also, since you only have a single executable, you can ship that to all of your users/customers, and give each a tailored config file. You can totally control & change the functionality of your software just by changing the config file. You might want to think about that.

Access global variable value in different .c files present in different paths

I have 2 files: Sod/iload/iload.c and
Item/itemrule/itemrule.c, and I want to access a variable defined in iload.c which is defined in itemrule.c.
To do this, I made and defined a global variable in iload.c, and I tried to access this variable in itemrule .c with the extern keyword, but it is always 0.
I'm worried that it might be because the files have different paths, does anyone know how I can access this variable?
The usual idiom is to use an extern declaration in a header file and include that wherever the global is needed.
// foo.h
// Make the global visible in any C file that includes this header.
extern int my_global_var;
// foo.c
#include "foo.h" // Not really needed here, but fine.
int my_global_var;
...
// bar.c
#include <stdio.h>
#include "foo.h" // This one makes the global visible in the rest of the file.
void do_something(void) {
printf("my global var's value is: %d\n", my_global_var);
}
Note that using globals like this in a program of any significant size or complexity can lead to messy, bug-prone, and hard-to-change code. Not a great pattern to follow.
I would like to offer an alternative to Gene's answer. In my experience there are two main ways to share variables across modules (compilation units):
1) "Getters and Setters".
2) Externs.
Depending on what kind of team you're working with, they'll have a preference for one or the other. C functions by default have external linkage; you need to force internal linkage via the static keyword in front of the function name if you don't want this.
1) Getters and Setters:
// foo.c
#include <stdio.h>
int my_global_var = 0;
...
Then you can follow it with externally-linked getters and setters. i.e.:
int get_my_global_var(void)
{
return my_global_var;
}
void set_my_global_var(int var)
{
my_global_var = var;
}
This is done within the c file (module). It will be the getters and setters will be able to be called from any other module and they will get and set the global variable my_global_var.
2) Externs:
// foo.c
#include <stdio.h>
int my_global_var = 0;
...
An alternative to getters and setters is to use externs. In this case you add nothing extra to the module that contains the global variable you wish to access/modify (my_global_var).
// bar.c
#include <stdio.h>
extern int my_global_var;
...
Notice the syntax here; when we use the extern keyword, we don't initialize it as anything. We are simply infoming the compiler that the global variable my_global_var has external linkage.

Change a extern variable from 2 C files

I want to be able to modify a variable from one C file and see the changes of that variable on the other one
Here are my C files:
file1.c:
#include "myheader.h"
int
main( void )
{
printf("Variable %d\n", var);
}
file2.c:
#include "myheader.h"
int main(void){
int var = 1;
var = var + 1;
}
The header file looks like this:
extern int var;
Now, I want to run file2.c first and than when I run file1.c print the incremented value of var. Ideas?
I think I am doing everything like this answer, but can't make it work.
PS: Just started learning C.
Each of your "files".c has a main function and thus will compile into a separate executable.
So you can't have one executable increment a variable in its own address space and then have another executable see the change in someone else's address space - the other executable will have an own variable in its own address space. Unless you would use advanced inter process communication (but that is Lesson 42).

Defining Global variable, Which is going to be used by multiple .c files

I needed to define several variables (Global variables), which are going to be used by many .c files. Variables like String array, File Pointer, Int etc.
Situation : FileX.h
Different c files(FileA, FileB, Filec, FileD) compiled with -c option individually(FileX.h have been included by all) then some of the files compiled again by combining them. When these are compiled individually No error pop up, but When they are compiled in a group (FileA.o, FileB.o and FileC.o), It pop ups Error. Is there any way to solve it. I thought of solving this with extern but seems this would also pop up error also.
Any suggestion please ?
I don't want to define variable in each .c file
I have String array so i don't want to define them every file
I'm assuming you get a multiple definitions error because your header looks like
global_variables.h
int global_a = 10;
int const global_b = 20;
What you need is
global_variables.h
extern int global_a;
extern int const global_b;
global_variables.c
int global_a = 10;
int const global_b = 20;
Edit: Further explanation:
Now in all your other files that need the global variables all you need is:
other_file.c
#include "global_variables.h"
void some_func(void){
global_a = 5; /* ready to use */
}
other_awesome_file.c
#include "global_variables.h"
/* and now you can use all globals */

Resources